見出し画像

Github Copiliotを使って単機能のアプリを実装した感想

もう少し実装に取り組んでから書くかなと思っていたのですが、存外書くネタというか考えた項目がリストに出てきたので、まだ1000行も書いてない所ですが、現段階のスナップショット、感想として書かせて頂きました。

どう使ったか

Rustとtauriというフレームワークを使って、Windows向けの単機能アプリを実装しました。
まだ途中なのですが、とりあえず動くようにはなっています。
試しながら作ったら動く所まで出来てしまったので、first commitでほぼ全部コミットするというヤクザな事をしています。

完全に新規の開発で、かつかなり小規模なものですので、その前提でお読みください。

補完の例

私はなるべく普段からコードを書く時はTDDで書くようにしており、テストから始めました。

#[test]
    fn test_parse_url() {
        let line = "Dr.Hogehoge (1995). Article Title, 170–175. https://doi.org/12.3456/j.1234-5678.1995.tb00123.x";
        assert_eq!(parse_line(line), "https://doi.org/12.3456/j.1234-5678.1995.tb00123.x");
    }

この時は補完は使っていません。

問題は実装コードで、関数名と引数を書いた所以下の実装を即座に出してきました。

fn parse_line(line: &str) -> &str {
    let mut url = "";
    for word in line.split_whitespace() {
        if word.starts_with("https://doi.org/") {
            url = word;
        }
    }
    url
}

殆どスニペットツールです。違うのはスニペットの元になるのがGithubの膨大なデータであり、かつそれを検索する必要もないという所。

いい所

言語機能が曖昧な部分でもググらず書ける

簡単なfor文でもググってしまう、というのはエンジニアで特定言語に詳しくない時のコンプレックスとしてよく引き合いに出されますが、機能の存在さえ知っているならば、コメントに `//hogeをループ` と書くことで実装出来ます。

特に馴染みがなくて構文としては知っているものの使いこなせていないmatch式を1発で出してくれたのはとても助かりました。

// exist_doiがエラーを返した場合はNG、そうでなければOK
    match exist_doi(url).await {
        Ok(exist) => {
            if exist {
                result += "[OK]";
            } else {
                result += "[NG]";
            }
        }
        Err(_) => {
            result += "[NG]";
        }
    }

動くコードを書くのが早い

当たり前のようですが想像以上でした。提案されたコードを読んで理解する事さえ出来れば、提案コードを次々と追認していくだけで機能が出来上がっていく感覚がありました。

ライブラリを含んだ提案をする

一般的に使われているライブラリの存在を知らずに機能を作り込んでしまう、というのは避けたいと思いながらも対策が難しい所ですが、copilotはライブラリを含んだコードを提案してくれます。

悪い所

部分最適に集中するのでコンパイルが通らないことがある

私にとって不慣れなRustだから特に感じる事かもしれないのですが、今取り組んでいる関数の実装は次々に出してくるものの、コンパイルが通らないコードになっており、その原因解決には役立たないため解決に苦戦しました。

特にasync/awaitを使う関数の実装に苦労しました。

copilotに指示するコメントが残る

私は基本的に本文中のコメントは無い方がよいと思っています。変数名や関数名で不十分な場合にやむを得ず使うというレベル。

ですがcopilotに対してはコメントで指示を出すため、コードと意味が重複したコメントが必ず残ります。手動で消していくのも面倒だし時々忘れてコミットされてしまうこともあります。

補完に置き換えて消えてくれればいいのに…

綺麗なコードは期待しない方がよい

動くコードを最速で作る事に焦点を当てるべきで、仕様を満たした上で綺麗なコードにするには人間の手が必要そうです。

ライブラリのバージョン指定等はしてくれない

さきほどはライブラリを使ったコードを提案してくれるというメリットを書きましたが、Cargo.tomlにライブラリを追加する作業は手動で行う必要があります。この時初めて、copilotが提案したコードが最新バージョンでは削除済みの古いメソッドを利用している事が分かりました。

関数切り出しはしない(多分)

適切な単位で関数を切り出す事は職業プログラマーであれば当たり前に行なっているかと思いますが、copilotは手続き的に今カーソルがいる場所に書き続けます。設計はまだ人間の仕事です。

私の思うベストな使い方

以上を踏まえてですが、私は原理主義的なテストファーストこそcopilotを使う上でベストに近いと思っています。
テスト書く時にcopilotを頼るかはどっちでも良いと思います。

テストを先に書いてさえいれば、コメントを書かずとも仕様を満たす関数をおおむね書いてくれるので、後は不足している部分を補足するだけで済みます。また、関数設計をテストを書く時点で出来るので、copilotの書いたコードを後から関数に切り出すような手間もありません。

もし実装コードから書き始めると、copilotが高速で出力するコードを自分で検証することがボトルネックになるだけでなく、実装を理解した上で後からテストを追加しないといけないコードの山ができてしまう問題もあります。
テストコードを書かないでリリースするのはもってのほかとして、copilotの書いたコードをどうテストすべきか、後から考えるのは大変です。

この先

すでに業務利用されている方からは、コードベースが巨大化すると上手く動かなかった、というコメントも聞いています。自分でも試してみたい所です。

後はアルゴリズムやデザインパターンを使う場面がどうなのか気になります。もうアルゴリズムを学ばなくていい、なんてことにはならないと思いますが、実装はある程度定型化しているから、AI任せでできるかも……

この記事が気に入ったらサポートをしてみませんか?