ディスカッション
久松氏:
公式のドキュメントだけでは現場レベルの特徴や利便性を十分に把握するのは難しいと思います。そこで、GoやRustがどのように現場で活用されているのか、お二人にお話しいただきたいと考えています。
今回は100名以上の方々が参加されています。自走式での言語活用や、転職を機に新しい言語でのプロジェクトを考えている方々にとって、参考になれば幸いです。
では早速、一つ目のテーマにいきましょう。
GoとRustを主な言語として選んだ最大の理由や動機は何ですか?
久松氏:
プログラミング言語やその特性、利点、プロジェクトでの役割、パフォーマンス、セキュリティなど、多角的な視点からお二人の話を聞きたいと思います。まずはyukiさんからお願いします。
yuki氏:
Rustに出会ったのは2017年頃のことです。当時は金融機関向けのリスク管理計算システムをJavaで開発していました。その中で並行処理を多用する場面が多かったのですが、そこで多くの問題が発生していました。
そんな中、ある日はてなブックマークなどを眺めていたとき、Rustは並行処理や変数の可変性の制限などを言語レベルで厳密に管理してくれるという記事を発見し、それがRustに興味を持ったきっかけです。JVMだけでは達成できないような高パフォーマンスや、Javaの言語仕様ではカバーできない特定の制約に対処できるとのことで、Rustを使い始めました。
久松氏:
tenntennさんはいかがでしょうか。
tenntenn氏:
私が初めてGoに触れたのは、多くの人がGoを知るよりもずっと前、おそらく2011年か2010年頃です。当時はまだ正式にリリースされていなく、Goの具体的な用途も明確ではありませんでした。私がGoを始めた理由は二つあります。
一つ目は、Googleが開発したという点に興味があったからです。二つ目は、当時大学院生で、研究で使えるかもしれないと思ったからです。Javaでも開発をしていましたが、何か新しい言語を試してみたいと思い、D言語も検討しましたが、結局はGoを選びました。
久松氏:
ありがとうございます。では、ここからはさらにディスカッションを深めていきましょう。
それぞれの言語を比較した時に、シチュエーションごとにどちらが適正などはありますか?
久松氏:
GoとRustを比較する際に、どちらがどのようなシチュエーションで適しているのかについてお聞きしたいと思っています。プロジェクトの性質、スピード、安定性、平行性、メンテナンスといった多角的な観点が考えられると思います。以前別のイベントで他のプログラミング言語の比較についても話したことがあり、その際には参加者のバックボーンについても触れられました。
お二人とも、プロジェクトリードや言語選定に関わった経験があると思うので、その点についてもぜひお聞きしたいと考えています。次に進む前に、tenntennさんからお話をいただければと思います。
tenntenn氏:
Rustについては詳しくないので直接比較は難しいですが、Goは最近よく選ばれる言語です。Goは開発効率に焦点を当てて設計されているため、チームでの開発が非常にしやすいという点が採用される大きな理由です。また、クラウドやミドルウェアでGoが多く使用されているので、スケーラビリティを求めるシステム、特にバックエンドでよく使われています。
久松氏:
ありがとうございます。それでは、yukiさんはいかがでしょうか。
yuki氏:
まず、Rustが一番力を発揮するのはシステムプログラミングの領域です。これには組み込みOS、ブラウザのようなメモリ管理が非常に重要なアプリケーションが含まれます。
一方で、RustをWeb開発など他の用途で使おうとすると、他の言語では経験しないような困難があることは確かです。
ソフトウェアの中で、とくに高速化が必要であったり、あるいはハードウェア側の制限などの理由で使用可能なメモリ量が少ないなどの理由で、C++が用いられている箇所にRustを代用することは十分可能です。実際、私たちの会社でもC++を使っていた部分をRustで置き換えるような作業を最近行っています。
Goに関してですが、私自身、『ISUCON(イスコン)』というイベントにおいて、ベンチマーカーと呼ばれるリクエストを送ってスコアを測定するアプリケーションの実装でGoを使った経験があります。このアプリケーションでは多くの並行処理が必要ですが、Goの並行処理のプリミティブが非常に良く設計されているため、書きやすかったです。Goは並行処理が多用されるような場面に特に向いているという印象を持っています。
Goでのプログラミングは手軽で、高いパフォーマンスを出せるアプリケーションを作成することが可能です。この手軽さとパフォーマンスのバランスがGoを特徴付けるポイントだと思います。
久松氏:
C++の一部をRustに替えた場合、パフォーマンスはどれくらい向上するのでしょうか?
yuki氏:
パフォーマンスに大きな変化はないと考えられます。C++をRustに替える主な理由は、ビルドツールの利便性やコードの安全性、さらには開発者の好みが影響していると思います。速度面で言えば、完全に計測環境や条件依存で、条件次第ではC++もRustもそれぞれ優れているケースがありますが、Rustに変えたからといってC++よりかなりパフォーマンスが向上するといったような、劇的な変化は期待しない方が良いと思います。
久松氏:
ありがとうございます。tenntennさん、Goの選定とマイクロサービスについてよく議論されると思いますが、これらを一緒に考慮するべきですか?それとも、yukiさんが言ったように部分的な変更から始めてもいいのでしょうか。この点で何かアドバイスがありますか?
tenntenn氏:
新しいプログラミング言語を導入しながらマイクロサービスを入れ替えるのは、非常に困難だと考えています。例えば、現在PHPを使用している組織がGoを採用する場合、コマンドラインツールなど、Goで比較的簡単に作成できる部分から始めることをお勧めします。
久松氏:
ありがとうございます。それでは、質問が一つ来ていますので、それに移りたいと思います。
RustをWebAPIで使用するのは過度だと感じますか?
yuki氏:
ポジショントークをするならば、Rustを使って開発してみたいと思ったらやってみるのが一番だと思います。ただ、Rustに詳しい方が一人いると、そのプロダクトへのRustの導入が円滑に進みやすいとは思います。
もちろん、RustのWebサーバーの実装への導入は、余計な苦労をたくさん持ち込み「やりすぎ」と感じることもあるとは思います。重要なのは、きちんとRustを導入する目的や狙いを定め、導入によってどのようなペインを回避できるかを考え、チームに伝えてから導入することです。
WebAPIの場合であっても速度が求められるケースもありますので、速度面での期待をこめてRustを導入するのは理にかなっています。私が聞いている限り、Rustの言語仕様の豊富さを期待して導入する人も多いようです。パフォーマンスや言語仕様から来る堅牢で保守運用のしやすいアプリケーションの構築が目的なのであれば、「やりすぎ」ではなくなる可能性があります。
重要なのは導入する目的で、その目的によって当然ですが、Rustの使用に対する印象は大きく変わるでしょう。
久松氏:
ありがとうございます。先ほど触れたように、前回KotlinとScalaについて、専門家を招き話をした際、どのような組織やエンジニアがこれらの言語に向いているか、逆に向いていないかについての議論が盛り上がりました。tenntennさん、Goについての意見はいかがでしょうか?
tenntenn氏:
Goは難しい言語ではありません。正しく使えば、多くの組織や場面で適していると思います。ただ、例えばモバイルアプリの開発などは適していないかもしれません。私の所属しているスタートアップもGoを利用していますし、大手企業、例えばGoogleなど海外の大きな企業でも使われています。
組織の規模による影響は少ないと感じます。ただ、特定の言語にこだわりがある場合は、移行は難しいかもしれません。
久松氏:
ありがとうございます。yukiさん、Rustについて、何かご意見はありますか?
yuki氏:
私たちの会社でも、組織規模が大きくないチームでRustを使用しており、大きな問題は生じていません。組織の規模はRustの使用に直接的な影響はないと感じています。しかし、RustでWebアプリケーションを一度作成・運用した経験がある人が少なくとも1人は必要だと感じます。そうでなければ、実際の運用が難しいという印象です。
ただ一方で、私も経験があるのですが、Rustを使用したいと考え実際に採用したものの、チーム内全員がRust初心者だったようなチームがありました。そのようなチームはやはり苦戦していました。
その理由として、ネット上のRustのサンプルコードが少ないこと、国内の出版物に実用レベルのアプリケーションのコードサンプルを含むものが少ないこと、そしてRust特有の言語機能(所有権、ライフタイム、トレイトなど)に初心者がつまずく傾向があるためです。
これらの理由から、少なくとも1人はRust経験者(少なくともプライベートでRustを使って一度アプリケーションを構築した経験がある人)がいる組織だとうまくワークするだろうと考えます。これはどのプログラミング言語の導入時であっても言われる話かもしれませんが、Rustでも同じです。
久松氏:
ありがとうございます。確かに、誰も経験がないままプロジェクトを進めると、どのプログラミング言語でも完成後のイメージが難しいですね。Q&Aから関連性の高そうな質問をピックアップしてみたいと思います。
セキュリティの観点で、RustとGoどちらが適しているか
yuki氏:
「セキュリティの観点」の「セキュリティ」という言葉が何を指すかによって大きく答えが変わります。例えばセキュリティでよく問題になるメモリ安全性の一例としてダングリングポインタを防ぎたい場合、Rustは静的解析でそのような問題が起こらないように設計されています。その点で言えば、Rustが強いと言えます。
tenntenn氏:
個人的な印象ですが、セキュリティの面ではRustが適しているように思います。しかし、どちらにせよ、重要なコードを変更することはリスキーです。
久松氏:
ありがとうございます。それでは、メインテーマの第3項目に進みたいと思います。
現場ではGoまたはRustではウェブアプリケーションフレームワークを利用されますか?
どのようなフレームワークが使われているのか、また、フレームワーク選択に影響を与える要因は何かという点ですね。特に、選定する際のポイントや注意点についても詳しく知りたいとのこと。tenntennさん、どうぞお答えいただけますか。
tenntenn氏:
WebフレームワークはGoにも存在し、Gin、Echoなどがよく利用されています。しかし、Goはマイクロサービスの文脈でよく一緒に議論されるgRPCといったテクノロジーともよく組み合わされるため、RESTfulなWebフレームワークを使用していない組織も多いです。
GoのWebフレームワークは一般的に薄く、標準ライブラリのnet/httpパッケージを直接使うケースが多いです。次のバージョンでは標準ライブラリが大幅に改善される予定なので、将来的にはフレームワークが必要なくなる可能性もあります。
久松氏:
はい、ありがとうございます。次にyukiさん、いかがでしょう。
yuki氏:
RustではWebアプリケーション用のサードパーティライブラリを使用することになります。Rustは標準ライブラリが薄いため、Goとは違い、標準ライブラリで簡単にWebアプリケーションを扱うことできません。
業務でよく使われるのはactix-webとwarpです。warpはactix-webと比較するとマイナーですが、TwitterのScalaフレームワークFinchにインスパイアされています。最近人気が出ているのはAxumというクレートで、使いやすさが重視されています。
Axumは特に、コンパイルエラーメッセージをカスタマイズする機能があり、それが使いやすさに寄与しています。ただ、Axumはまだ開発途中で、マイナーバージョンが変わるとAPIも変わる可能性があります。そのため、現在は安定性のあるactix-webを主に業務では使用しています。
Rustの非同期処理は、サードパーティの非同期ランタイムライブラリ、例えばtokioやasync-stdに依存しています。非同期処理に関するライブラリは多数ありますので、興味があれば調べてみてください。
tenntenn氏:
RustとGoは思想が違うなと感じました。Goは標準ライブラリを非常に重視しており、一般的に必要な機能は基本的には標準ライブラリでカバーされている傾向があります。これは、みんなが同じものを使うという文化が根付いているからです。一方で、Rustはよりミニマリストなアプローチをとっていると感じました。どちらが良いか悪いかは一概には言えないと思いますが、それぞれが持つ特性は面白いです。
yuki氏:
Rustの標準ライブラリが薄い主な理由は互換性の問題を回避するためと言われていますが、さらに加えて個人的に思うのは、Rustは使用される領域が非常に広いことも要因のひとつなのではないか、ということです。
ベアメタルな環境(OSやそのほかのソフトウェアがインストールされていない環境)でも動かさなければならない場合もあるため、必要に応じて標準ライブラリを剥がすこともあります。
たとえばHTTPのルーティングなどは、そうした環境では使わない可能性が高く、使わないにも関わらず標準として用意しておくと無駄になります。Rustのメンテナンスの観点から考えても、標準ライブラリのメンテナンスコストが上がっていくことになります。
そのような理由から、Rustのライブラリは意図的に小さく設計されているように思います。この点はGoとは確かに異なります。
久松氏:
ありがとうございます。それでは、次のテーマに移りましょう。
他の言語からGoやRustに移行する際の経験や、その際の課題、学びは何でしたか?
yuki氏:
業務での経験は主にJavaとScalaですが、Rustについて学んだ最大のポイントは、同じ処理を行ってもRustのリソース使用量が非常に少ないという点です。特にメモリ使用量がかなり減る印象を持っています。
また、Rustではメモリ制御が非常に細かくできます。例えば、JVMのガベージコレクション(GC)ではオブジェクトの解放タイミングが不明瞭な場面がありますが、Rustではそのタイミングがはっきりとわかる(不要になったらすぐに解放する)ので、それが非常に良い点だだと感じています。
一方で、課題としてはRustのエコシステムがまだ成熟していない面があります。他の言語にはあるライブラリがRustにはなく、自分で実装する必要がある場面もしばしばあります。しかし、ユーザー数が増えればこの問題も解消されると期待しています。
久松氏:
スタックオーバーフローで見ると、若い人たちが学びたい言語ランキングでRustが1位になっていることがあるようですが、このトレンドについてどう思いますか。ユーザーが増えているように感じますか。
yuki氏:
はい、最近その傾向があると思います。前職で新卒の採用も行っていたのですが、「Rustを使っています」という学生が増えている印象を受けました。
久松氏:
ありがとうございます。tenntennさんが学生と交流する際、Rustを使用しているというコメントを頻繁に聞くそうですが、GoやRustの使用が増えていると感じる点はありますか?
tenntenn氏:
Goの使用が増えてきたのは以前から感じていますが、特にRustの使用も増えていると感じます。学生に利用しているプログラミング言語について尋ねると、Rustを勉強しているという方が多いようです。
久松氏:
ありがとうございました。次の質問はyukiさんに特に向けています。Rustでガベージコレクション(GC)がないことのメリットを実感した経験はありますか?
yuki氏:
先ほども述べたとおり、オブジェクトの解放タイミングがわかりやすい点です。ただ、GCがないことによって、たとえばRustでは所有権やライフタイムなどの別の複雑性を持ち込んでいることは確かなので、GCのあるなしにはメリットとデメリットがあり、一概にあらゆる場面でそれが良いと言い切れないのもまた事実です。
久松氏:
ありがとうございます、それでは次の話題に進みましょう。
今後、GoやRustの技術やエコシステムがどのように進化していくと予想しますか?また、それに伴い現場での使用シーンにどのような変化が起こると考えますか?
久松氏:
新たな機能、ツール、ライブラリ、パフォーマンスとセキュリティの向上、さらには将来のトレンドと影響についての意見をお聞きしたいと思います。yukiさん、お願いします。
yuki氏:
Rustには低レイヤーとそれ以外の用途で異なる考慮点があると思います。例えば、OSやブラウザの開発においては、すでにRustは多く使用されています。国内では、自動運転に関連する企業がRustでOSを作っているという話も聞きます。
さらにGoogle Chromeにも部分的にRustが採用されているようです。最近では、Linuxのデバイスドライバーにも使われ始めています。こうした分野でのRustの使用が今後も拡大していくでしょう。
こうした分野では、メモリの安全性に関しての課題が多かったようです。例えば、Googleが発表する資料では、メモリに関する脆弱性が取り上げられています。Rustはこの問題を効果的に解決できるので、これを大きな理由として採用が進むと考えられます。
Web側に関して、Webサーバーの開発では、使用するプログラミング言語によらず期待する結果は得られると感じます。私自身もScalaやJavaでの開発経験があり、特に大きな問題に直面したことはなかったので、結果が大きく変わることはないと思います。そのため、この分野でRustが主流になることは、一定の課題があるかと思います。
アプリケーションの大部分を構築するような使われ方をするかは疑問です。一部のコンポーネントの高速化など、特定の目的でRustが採用されることが多いと感じます。私が見る会社内の状況からも、このような限定的な使用が主流だと思います。
久松氏:
わかりました。tenntennさん、いかがでしょうか?
tenntenn氏:
Goが使われるシーンは増えており、Go Conferenceのスポンサー企業も50社ほどに増えています。これはGoエンジニアを求めている企業が増えている証拠です。
Goの進化については、公式ブログで報告されているように、基本的にはGoのバージョン2というバージョンは出ない予定です。後方互換性を崩すような大きなバージョンアップが必要な場合のみGoのバージョン2が考慮されるとされていますが、そうなる可能性は低いと言われています。
そのため、Goは後方互換性を保ちながら進化すると見られ、これが言語の安定性につながっていると思われます。
新しい機能が追加されることに制限はありません。例えば、最近のGoのツールチェーンでは、新しいバージョンが必要な場合はツールチェインが自動で新しいバージョンをダウンロードしてインストールされる機能が追加されました。
さらに、for文のループ変数の扱いが変わるアップデートがあったり、新しいfor range文のいわゆるイテレータと呼ばれる仕様の追加が提案されたりと、攻めた仕様も多くなっています。
標準ライブラリにも新機能が増えており、例えば構造化ログのライブラリが追加されたり、バージョン1.18からはジェネリクスが導入されるなど、機能が急速に増加しています。新機能が後方互換を保ちながらも追加されている流れがあります。
これらの変化に対して、現場のエンジニアはしっかりとキャッチアップする必要があります。新しい機能が次々と追加されているので、その波に乗り遅れる可能性もあります。
GoとRustそれぞれに欲しい機能などあれば教えていただきたいです
久松氏:
ありがとうございます。関連するQ&Aで「GoとRustそれぞれに欲しい機能などあれば教えていただきたいです」という質問が来ています。tenntennさん、お願いできますか?
tenntenn氏:
実は私が望んでいたジェネリクスとイテレーターは既に取り込まれていたり、導入される予定がありますので、大体の要望は満たされています。ただ、エラー処理についてはまだ改善の余地があると感じています。
久松氏:
ありがとうございます。yukiさん、いかがでしょうか?
yuki氏:
ビギナーのレベルを越えた話になりますが、私が注目しているのは主にふたつです。ひとつめは「Async Iterator」と呼ばれる非同期ストリーミング処理です。ふたつめは非同期処理におけるキャンセル機能です。Goではこのキャンセル処理がかなりスムーズに行えるのですが、Rustで同じことをすると非常に手間がかかります。
特にISUCONのベンチマーカーをRustで書くのは、Goのような手軽なキャンセル機能がないと厳しいと感じています。そのため、非同期処理周りの機能が今後も充実していくと嬉しいです。
非同期処理、特にRustでのasync/awaitについてですが、この機能は2018年頃に新しく追加されました。しかし、実装がまだ完全ではなく、いくつもの未実現の機能や解決すべき問題点が存在します。
Rustでの非同期処理には特有の困難があり、特にメモリ安全性を確保したり、コンパイラレベルで並行処理の安全性を守る必要があるため、他のプログラミング言語に比べてその対処が大変です。これらの課題が解決されたら、非常に助かると個人的には思います。
久松氏:
了解しました。それでは、このテーマについての説明をここで終わりにして、次に質疑応答のセッションに進んでいきましょう。
![[tenntenn氏×Yuki氏]GoとRustはどんな現場で使われている!?](https://images.microcms-assets.io/assets/0424eb4d08074d81bfa98eb3dc10071c/20fae8923f50428884f7f3f55357d0aa/report_GO_Rust.png?w=3840&q=75&fm=webp)




