go でGithub Copilot を軽く触ってみた

# なんの記事？

golang でGithub copilot の基本機能を使ってみたログと所感

# Github Copilot とは

```
関数名とコメントから、関数のコードを丸ごと自動補完するAIプログラミング機能
```

https://copilot.github.com/

https://www.itmedia.co.jp/news/articles/2106/30/news063.html

# 基本操作

- `Tab`で補完
- `Option+]` (or `Option+[`) で次/前の候補 (Mac OS)
- `Esc` で補完を消す
- `ctrl + enter` で他の候補の一覧


# 実際にgo で触ってみる

環境：VSCode, Mac

vscode でインストール後やることはシンプルでコードを入力してタブで補完するだけ。
提案方法には
- 関数名から補完する方法
- コメントから補完する方法

があるようで、どちらも試してみた。

## 関数名で補完

func main() なんて書いてみると適当な加算のサンプルコードが提案された。
こんなふうに提案されるのか。
![スクリーンショット 2021-10-27 23.18.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262578/789a9224-86ee-6bc2-3672-99e88a7cecc9.png)

`option + [` で次の提案を見てみるとhello world に
![スクリーンショット 2021-10-27 23.18.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262578/2992bd77-af75-02f8-4324-3aeb8023096a.png)

再度押すと小文字のworld になったり。
![スクリーンショット 2021-10-27 23.18.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262578/6fd7869b-d33a-f326-f5ee-a5b5084240af.png)

***

より実用的なコードをしようとstring のスライスからint のスライスに変換する関数名を入力してみた。

![スクリーンショット 2021-10-27 23.20.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262578/8597c976-cdc3-7d0f-ad0a-02edf071ead6.png)

すごい、シンプルな内容ではあるが一瞬でやりたいコードの提案をしてくれた。
実際に`Tab`を押すことで一瞬でそのコードが書ける。

（でも、スライスの長さ決まってるなら`var result []int` よりも`result := make([]int, 0, len(s))` のほうがいいよねなんて思ったり。もちろんすべてが真ではないし、もしかしたらバグコードが提案される可能性も否定できないことに留意したい）

さらにmain関数でこれをprintln でもしてみようかと思って書き始めようとすると
![スクリーンショット 2021-10-27 23.21.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262578/e8a0aad5-ba4e-b286-476c-8f17aae32fbc.png)

との提案。ここまでやってくれるのかと。
Github Copilot は単なる点での提案ではなくコードのコンテキストを考慮した提案をしてくれるようだ。
思ったよりもよく考えてくれている。

`tab` を押して提案された記述をそのまま使い、次に行うのは出力。
ここまで来るとGithub Copilot先生も「やっぱりな」と思ったのだろうか、当然のようにfor と打つだけでインデックスを覗いたfor 文とprintが提案された。さすが。

![スクリーンショット 2021-10-27 23.22.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262578/8d4115e7-0b9b-3dc8-621a-97be50f36c56.png)
![スクリーンショット 2021-10-27 23.22.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262578/7ccbe662-0b14-bb86-1ea4-dd339d071f81.png)

こんな感じでスイスイとｓtring スライスをint スライスに変換して出力するサンプルができてしまった。

``` go
package main

import "strconv"

func main() {
	println("Hello, world.")
	s := stringSliceToIntSlice([]string{"1", "2", "3"})
	for _, v := range s {
		println(v)
	}
}

func stringSliceToIntSlice(s []string) []int {
	var result []int
	for _, v := range s {
		i, err := strconv.Atoi(v)
		if err != nil {
			panic(err)
		}
		result = append(result, i)
	}
	return result
}
```

提案の早さについても特に気になる時間はかからず、これくらいの簡単な関数であれば1秒もかからず提案してくれた。

### おまけ
有名なアルゴリズムとかは当然のように補完されるようだ
![スクリーンショット 2021-10-27 23.25.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262578/e90a94cd-ce20-ebea-a7d0-d831cff52f19.png)
![スクリーンショット 2021-10-27 23.25.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262578/41fd26a6-10fc-0669-f06c-6d4dde80308b.png)


## コメントを書いて補完

Github Copilot はコメントから文章を解釈してコードの提案をも行ってくれるようだ。
実践してみる。

たとえば上記のfibonacci 関数は再帰での記述になっていて、計算量がO(n^2)になってしまい重い処理になることが予想される。可能であれば再帰を使わずに書きたいことが多いものだ。
単に`option + [ ` で次の提案を探す方法もあるが、より具体的にコメントからより記述的に書く方法を試してみた。

再帰を使わないフィボナッチをgetする関数と書こうと入力していると…
![スクリーンショット 2021-10-28 11.04.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262578/9bccc77d-66be-e5bf-1f6b-c8a4ada27c20.png)
ここから補完！ナイス！　これがやりたかった！

実際に提案されたコード：

``` go
// get fibonacci number not to use recursion
func fibonacci2(n int) int {
	if n == 0 {
		return 0
	}
	if n == 1 {
		return 1
	}
	a := 0
	b := 1
	for i := 2; i <= n; i++ {
		a, b = b, a+b
	}
	return b
}
```

これで頭も再帰も使わずフィボナッチ数をゲットする関数を書くことができた。

また前述の通り、`ctrl + enter` で他の候補の一覧も閲覧できる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262578/bf54965c-1854-055d-32cc-6b8898b023f9.png)

なるほど。便利

こんな感じで、やりたいことがより具体的で複雑になりそうなときはコメントからの補完を使ったほうが提案の精度も高くなるように思えた。

### おまけ

適当なコメントしてみて提案を見るのも面白い

// pizza
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262578/acd2f32f-bc56-7c29-0505-bd71c6803993.png)


# まとめ

GitHub Copilot は思っていた以上に立体感があり、コードのコンテキストを考慮したより人間的な提案をしてくれていた。ただ注意したいのが書くコードが常にベストを出すとは限らない。
どんな感じだっけーって検索してコピペするような作業的なコードについてはCopilot の利用がかなり効きそうだなという印象。
基本的には実装の方針の確認のために粗く利用して多角的に判断して採用するような使い方がいいと思った。