めまぐるしく変化するテックの世界。技術を身に着けるうえで学ぶべきポイントや学習環境なども年々変わっています。
そこで「もしもいまの環境で、テックのことをイチから学び直すことになったら、自分はどんな風に勉強したいか」というIFストーリーを通じて、技術との向き合い方を考え直してみる企画「テック転生」。
今回は、株式会社ヘンリー VPoE・松木雅幸(Songmu)さんに“自分だったらこう進めたい、Goの学習ロードマップ”を伺いました。
学び始める前に
Songmuです。今ではGoが得意なエンジニアとしてご存知いただいているかもしれませんが、そんな私がもし記憶を失い、改めてGoをイチから学び直すとすればどうするでしょうか。
そもそも、2025年にGoを学ぶ必要があるかどうかを検討しなくてはいけません。
そのために、Goがどのような言語で、自分にマッチするかどうかを知りたいところです。プログラミング言語にはそれぞれ得意領域や思想があるためです。現在の環境・トレンドにマッチしているか、自分が作りたいものを作りやすいか、自分がその言語で思考しやすいか、などを検討する必要があります。
配属されたプロジェクトでGoが使われているなど、新たに学ぶ必要に迫られている場合であってもそれらを知ることは有用です。言語が主にどのような課題に向いているかや、背景の思想を知っておくことで、その言語らしくないコードを書いてしまうリスクや、向いていないことをやろうとして変にストレスを感じてしまうリスクを低減できます。
幸い、Goは公式のドキュメントが充実しており、単なる仕様だけではなく、Go自体や思想背景に関する理解を深められるコンテンツが多く存在しているため、ここを参照するのが良さそうです。
例えば、"Go at Google" では、Goが開発された時代背景を踏まえ、どのような言語を作ろうとしたのかが書かれています。その他、"Effective Go" や "FAQ" なども充実しており、Goの思想を理解する助けになります。特に、FAQ内にある「なぜ新しい言語を作ったのか」という項目が印象的であり、以下に引用します。
Go is an attempt to combine the ease of programming of an interpreted, dynamically typed language with the efficiency and safety of a statically typed, compiled language. It also aims to be modern, with support for networked and multicore computing.
-- https://go.dev/doc/faq#creating_a_new_language
これらを踏まえると、Goがどのような言語であり、どのような言語でないかが分かってきました。
どのような言語なのか。
- 実行速度および開発速度両面での効率の良さとスケーラビリティを実現する言語
- 処理速度が比較的速い
- コンパイルも速く、クロスビルドも簡単である
- 並行処理を実装しやすい言語機能がそろっている
- 向いている適応領域
- Web、特にAPIやRPCサーバーといったマイクロサービス開発
- システムツールや低レイヤのシステムプログラミング
どのような言語ではないのか。
- 多くのモダンな言語が備えようとしているリッチな型システムや関数型のエッセンスを取り入れていない
- 実行速度が最速クラスというわけではなく、CやC++, Rust等と比べると遅い
他言語と競って言語機能を増やすようなことをせず、言語機能を絞り込むことで独自の立ち位置を獲得している言語と言えそうです。Goのオリジナル作者の一人であるRob Pike氏の "Less is exponentially more" という記事が、その思想を端的に表していそうです。
また、機能追加に対して慎重な側面はあるものの、近年ではジェネリクスが入るなど、着実に進化し続けています。速度が速すぎない分、追随しやすい言語だとも言えますし、実際、後方互換性をかなり大事にしており、実用主義的な言語と言えそうです。
独特な言語なので、少し奇妙に感じる部分もありますが、背景を知ることで少し納得できるようになってきました。実際に使ってみて分かる良さもあるだろうので、まずは学び始めてみることにしましょう。
学び始め
まず、Goの基本的な言語機能や仕様を学びたいところですが、どうすれば良いでしょうか。
先生を探す
可能なら身近にGoに精通している人を見つけたいところです。気軽に質問ができる「先生」がいると、学習効率が格段に上がります。もし、学びたい言語が他にもあり、その言語に精通している人が身近にいる場合、その言語をGoよりも先に学ぶ方が良いかもしれません。それくらい先生の存在は新しい技術を学ぶ上での有力な選択基準になります。私の場合、Perlコミュニティ繋がりでGoに詳しい人が身近にいるので、それらの人達に質問できそうです。
もちろん、最初から身近に先生がいるケースは稀なので、いなくても大丈夫です。また、後述しますが、言語を学んでいく中でコミュニティ繋がりで先生的な人を見つけることもできるかもしれません。
AIを活用する
今から新しい技術を学ぶ場合、ChatGPTなどのAIを積極的に活用しない手はありません。Goは新しめの言語ではありますが、それでも10年以上の歴史があり、その間に機能的に大きな非互換変更もありません。そのため、情報が十分に蓄積されており、LLMでの学習に適していると言えそうです。
とにかく、分からないことを何度も聞いたり、サンプルコードを出力させて自分で実行して読み解くなど、高速にフィードバックを回して、学習を進められます。
ただし、ハルシネーションのリスクがあるため、前提知識の乏しい初学者には扱いが難しい部分があります。そのため、AIが出力した情報を盲信せず、自分で動かしながら学ぶことや、情報源をAIに限定しないことが重要です。
書籍を読む
先に述べたように、Goは公式ドキュメントが充実しているため、書籍を読む必要はないようにも思います。しかし、私は新しい技術を学ぶときは、網羅的な全体像を掴むためにまずは一冊書籍を読むことにしています。今なら「初めてのGo言語」を買うのが良さそうです。
書籍を読むことで、個別の言語機能だけではなく、その言語の思想や哲学、歴史なども知ることができます。書籍には時間の経過による陳腐化のリスクがありますが、幸いGoは後方互換を大事にしている言語であるため、古くなっても基本的な部分は変わらなさそうです。
書籍を読む場合、最初から丁寧に通読はせず、全体像を掴むためにざっと読むだけにしています。その後、実際に手を動かしながら、必要なところを引いたり、ある程度慣れてきたら改めてしっかり読み返すようにしています。
実際に手を動かす
情報を得るだけではなく、実際に手を動かしてみないとなかなか言語は身に付かないものです。幸いGoにはTour of Goという公式のハンズオンチュートリアルがあります。また、Go Playgroundというオンラインの実行環境もあり、手軽に挙動の確認をしたり、不明なサンプルコードを共有して質問することができて便利です。
実際のプロジェクトから学ぶ
言語の特徴や仕様を把握しても、実際にプロジェクトを進めるとなるとまた違った知識が必要になります。Goに限らず、プログラミング言語を学ぶ場合、言語仕様だけでなく、その言語での開発にまつわる作法やツールチェインを把握することも必要です。
開発環境を整える
近年は、開発環境が言語機能の一部とも言えるほど重要になってきています。開発環境を整えることで、作法に従ったコードを書きやすくなりますし、当然、開発効率も向上します。セットアップも簡単になっているため、まずはしっかりと開発環境を整えることが重要です。
Goの場合は、エディタにVSCodeを使い、Go公式が提供しているGo開発用のプラグインを導入するのが手軽で良さそうです。これで、コードの自動整形やlinterによる警告や自動修正などが使えるようになります。これらに素直に従うことで、品質を保てますし、Goらしいコードを学ぶ一助にもなります。
Language Serverによる補完やリファクタリングも有用です。AI関連機能も使えるなら積極的に導入しましょう。これらは開発効率を向上させるだけでなく、Goを学ぶのにも役立ちます。
まず何か作ってしまう
作りながら学ぶか、学んでから作るかは人それぞれです。Web上では「作りたいものが先にあったほうが良い」とは良く言われるものの、実際には作りたいもののアイデアが最初からある人は少数派です。私も最初から作りたいもののアイデアが思い浮かぶわけではなく、ある程度学んで自分の中に手駒がそろって勘所が掴めてから「あれも作れるな」とか「これも作れるな」とアイデアが湧いてくるようになると実感しています。
最初から作りたいものがあるのはレアケースですが大きなアドバンテージです。その場合、すぐにリポジトリを作って開発を始めたいところです。Goはコマンドラインツールなど、小粒なツールを簡単に作れる言語でもあります。まずは、リポジトリに main.go
を一つ置くだけで小さく開発を始められる良さがあります。ちょっとしたものを作るアイデアは色々出てきそうです。
プロジェクトのリポジトリを精読する
社内にGo開発のリポジトリがある場合には、それを生きた教材にしたいところです。精読して、分からないところは同僚に聞いたり、ChatGPT等に食わせてみたりしながら理解を深めることができます。
参考になるOSSリポジトリを探す
プログラミングは一人の力でできることは少なく、開発チームやOSSエコシステムと協調する必要があります。エコシステムと協調せず、セオリーを無視した我流でガラパゴスな開発が行きすぎると、あらゆることを自前でやる必要が出てきてしまいます。結果として、定番のツールやライブラリの利用が難しくなり、開発速度や効率の低下に繋がります。また、自分が書いたコードを他者に再利用してもらうのも難しくなります。
定番のやり方が性に合わず、独自のやり方を取りたくなることはままあります。ただ、そもそもセオリーから外れた独自のやり方が優れている可能性は低いでしょう。それに、エコシステムやコミュニティによってセオリーが醸成されていくものでもあります。ですので、「郷に入りては郷に従え」の精神でまずはエコシステムに素直に従ってみることです。それでも性に合わない場合は、自分のやり方に閉じてしまうのではなく、オープンに提案し、他者を巻き込みながらエコシステムを作るくらいの意欲が必要です。
前置きが長くなりましたが、エコシステム上のセオリーや雰囲気を把握するために、OSSのコードを読むことが有効です。
幸い、Goは言語本体や標準ライブラリがOSSになっていますし、DockerやKubernetesなどGoで書かれたメジャーなOSSが多く存在します。特にGoの標準ライブラリは、Goらしいコードの書き方や、テストの書き方、エラーハンドリングの方法などを学ぶ上で参考になりそうです。エディタ上でコードジャンプして手軽に読めるのも嬉しいポイントです。
サードパーティのOSSプロジェクトからも知見を得たいところです。先に挙げたようなDockerやKubernetesでも良いのですが、これらは大規模で複雑あり初学者が参考にするにはハードルが高そうです。できれば、比較的小規模でシンプルなもの、さらに言うなら身近で親近感が湧きやすいものを探したいところです。
まずは、社内プロジェクトや自分が使っていたり、今後使いそうなOSSのツールやライブラリのリポジトリをGitHubから探してみることにします。GitHub検索を使いつつ、リポジトリのStar数やawesome-goなども合わせて参考にします。また、ChatGPT等に聞いてみたり、コミュニティや勉強会で話題のOSS、身近な人が関わっているOSSも参考にするでしょう。
私だったら、静的サイトジェネレーターのHugo、リポジトリ管理ツールのghq、ECSのデプロイツールのecspressoなどが候補になります。これらはコードサイズもちょうどよく、私も使っており、作者も知っている方が多いため、コードも読みやすいというメリットがあります。
コミュニティに参加する
さらに学びを深めるためにも、コミュニティにも参加したいところです。
学び始めのところで、AIに加えて書籍を読むこともお勧めしましたが、何かを学ぶにあたっては複数の情報源を持つことが重要です。コミュニティはそのための一つでもありますし、自分の知見をアウトプットすることで良質なフィードバックを得るための場でもあります。
まずは、勉強会やオンラインコミュニティを探して参加してみます。そこで発信されている情報を吸収したり、ウォッチした方が良いコミュニティヒーローを知ったり、一緒に学ぶ仲間見つけたりするところから始めたいところです。
そして、なるべく早く自分からも発信することを心がけます。ブログ記事や登壇、OSSへのコントリビュートなどの形で、自分の知見をアウトプットすることで実践的な知見を身に付けられますし、良質なフィードバックを得て学びを深める機会にもなります。そこから、先生的な存在を見つけられるかも知れません。
まとめ
このように私は複数の情報源を持つこと、自分で手を動かしたり発信をしながらフィードバックサイクルを作ることが、新しい技術を学び、身に付ける上で効果的だと考えています。Goをイチから学び直す場合にも同じようなアプローチをとることになるでしょう。
おまけ: 新しい言語を学ぶことは新しいプログラミングパラダイムを学ぶチャンス
新しい言語を学ぶことは、その言語の得意領域から新たなプログラミングパラダイムを学ぶチャンスでもあります。それが私が新しい言語を学ぶモチベーションにもなっています。例えば、私は以前Haskellを学んだときに関数型プログラミングに関する理解が一気に深まった経験があります。
Goは並行処理が得意な言語なので、Goを学ぶことは並行処理プログラミングの知識を深めるチャンスと言えます。そのために「Go言語による並行処理」などの書籍を読みながら自分で試してみたり、並行処理が活用されているGoのOSSを探して参考にしたり、開発に参加するなど、意識的に並行処理プログラミングを学ぶ機会を設けていきたいところです。
このようにテーマ設定をしながら新しい技術を学ぶことで、楽しく学び、技術力を磨き続けることができると考えています。ソフトウェアエンジニアとしての成長を楽しく続けていきましょう。