Slide 1

Slide 1 text

Java 開発者が Rust に入門してみた #ADC2022 髙市 智章 (Tomoaki Takaichi) Nov, 25, 2022 AItech Developer Conference 2022

Slide 2

Slide 2 text

自己紹介 @Takaichi00 tomoaki.takaichi.5 ・髙市 智章(タカイチ トモアキ) ・2022/05 CA 入社 ・エレベーターサイネージ ・Rust / Java でのシステム開発 共著: クリーンなコードへの SonarQube即効活用術 www.amazon.co.jp/dp/B086ML43DH

Slide 3

Slide 3 text

発表の流れ

Slide 4

Slide 4 text

❏ 主に Java を使ってきた自分にとって、Rust は今までにない概 念が多く、つまずいたポイントがいくつもあった (今でもつまず き続けている) ❏ Rust を始める6ヶ月前の自分に対して、「Rust はこんな言語で すよ」「Rust と Java はこんな違いがありますよ」と伝えるよ うな発表をコンセプトにし、これから Rust を触ってみようとい う方の参考になれば 発表をしようと思ったか

Slide 5

Slide 5 text

Rust 言語とは

Slide 6

Slide 6 text

❏ 2015年に正式リリース ❏ 静的型付け・コンパイラ言語 ❏ システムプログラミング言語 ❏ C / C++ に匹敵する速度を実現し、OS, 組み込み, ブラウザなど低 レイヤーを目的に作られた ❏ C 言語に加えて、Linux カーネルの開発向けプログラミング言語 として採用される (Linux 6.1 から) Rust 言語

Slide 7

Slide 7 text

Rust 言語 ❏ しかしモダンな言語機能も搭載されており、高レイヤーまであつかう ことができる ❏ 2019年の Rust Survey によると、利用事例が一番多いのは ”Web バックエンドアプリケーション” となっている 出典: https://blog.rust-lang.org/2020/04/17/Rust-survey-2019.html

Slide 8

Slide 8 text

Rust 言語の特徴 ❏ GC (ガベージコレクション) がない ❏ にも関わらず、メモリ安全+並行処理安全である ❏ ゼロコスト抽象化 ❏ プログラミング言語が持つ抽象化 (ポリモーフィズム・高階関数 など) の 機能をきる限り実行時ではなくコンパイル時に行うことで、実行速度の低 下やメモリ使用量の増加を防ぐことができる ❏ 独自の仮想マシン (JVM など) を持たず、直接機械語にコンパ イルされる

Slide 9

Slide 9 text

(軽く) Java 言語とは

Slide 10

Slide 10 text

Java 言語とは ❏ 1996年に最初のバージョンがリリースされる (Rust 誕生の19 年前!) ❏ 静的ページが主流だった当時、Java Applet を使えば簡単に動的ページが作れると いうところから人気を博す ❏ バイトコードにコンパイル → JVM がインタプリタ実行 ❏ プラットフォームに依存しないプログラム開発 ❏ GC / JIT コンパイラ がある ❏ エンタープライズシステムなどの利用例が豊富

Slide 11

Slide 11 text

ここまでの説明を聞いた 当時の感想

Slide 12

Slide 12 text

Rust のファーストインプレッション よくわからないけど、Java より早くて C 言語よ り安全、モダンな言語機能もあるしバックエンド でもよく使われている。 なんか行けそうな気がする! … でも、商用システムで使って大丈夫なの...?

Slide 13

Slide 13 text

Rust で Web バックエンド アプリケーションを開発してみた

Slide 14

Slide 14 text

(Java 以外の経験が少ない自分が) Rust でつまずいたポイント

Slide 15

Slide 15 text

基本文法でつまずく

Slide 16

Slide 16 text

Rust と関数型言語 ❏ Rust は関数型言語ではないが、関数型言語由来の文法や言語機 能が多く採用されている ❏ これからお話する Result, Option, Iterator は関数型の機能 が 元となっているが、慣れるまではコードを見ても何が起きてい るのかイメージしづらかった

Slide 17

Slide 17 text

Result ・Option 型 ❏ Rust には Go と同様に例外の機構はない ❏ エラーハンドリングには Result という列挙型 (関数型の Either が ベース) を使うか、パニックを起こして処理を強制終了させる方法がある ❏ 想定内のエラーであれば Result の Err を返すのが基本 ❏ Rust には null 機能が存在しない ❏ これは安全性向上のための意図的な設計 ❏ 存在するかしないかの値を表現したいときは Option という列挙型を利用 する

Slide 18

Slide 18 text

Result 型・Option 型と match 式 ❏ Rust にはマッチしたパターンに応じてコードを実行させてくれ る強力な match 式があり、Result ・Option 型のハンドリン グもやろうと思えばすべて match 式で対応することができる ❏ 最初の頃はひたすら match 式で対応していたが、シンタックスシュガー を使いましょうとよく指摘される TODO: サンプルコード

Slide 19

Slide 19 text

Result・Option 型 と シンタックスシュガー ❏ Result や Option 型は match 式以外にも様々なシンタックス シュガーを用いてハンドリングをすることができる ❏ しかし使いこなすまでには時間がかかった (今もなお苦戦中) ? 演算子

Slide 20

Slide 20 text

Result + Option と Iterator の組み合わせ ❏ Rust には Java でいう Stream API のような、Iterator という Trait が提供されている ❏ Iterator と Option, Result 型などが組み合わさった処理は自分で書 けるようになるまで更に時間がかかった

Slide 21

Slide 21 text

基本文法でつまずく ~関数型に慣れる必要がある~

Slide 22

Slide 22 text

Rust 特有の概念でつまずく

Slide 23

Slide 23 text

「GC がない」 かつ 「メモリ安全」 ❏ Rust には GC がないため、メモリ安全のコードを自前で実装し なければならない ❏ ただ Rust では「ライフタイム」「所有権」「借用」という仕組 みを使うことで、メモリ安全ではないコードはコンパイルを通 さないというアプローチをしている ❏ これにより、メモリ安全 + 高速な実行速度を実現している ❏ 多くの開発者はここに難しさを感じている ❏ 2020年の Rust Survey では、ライフタイム, 所有権・借用が Rust で難 しいトピックの上位を占めていた

Slide 24

Slide 24 text

所有権 ※ 今回は概略だけご説明します

Slide 25

Slide 25 text

所有権 ❏ 所有権のルールは以下 ❏ Rust の各値は、所有者と呼ばれる変数と対応している ❏ いかなるときも所有者は1つ ❏ 所有者がスコープから外れたら、値は破棄される

Slide 26

Slide 26 text

所有権 ❏ 下記のコードは所有権が起因でコンパイルエラーになる代表例

Slide 27

Slide 27 text

所有権 ❏ 関数に値を渡しても所有権が移り、下記コードはコンパイルエ ラーになる

Slide 28

Slide 28 text

所有権と借用 ❏ いちいち関数に値を渡すたびに所有権がなくなるのは不便 ❏ 関数に参照を渡すことで対応することができる (借用という)

Slide 29

Slide 29 text

所有権と Clone ❏ 借用の他にも、Clone という値を複製するメソッドを使うこと でも所有権をそのままにすることができる

Slide 30

Slide 30 text

どのように所有権と向き合うか ❏ 何も意識せずに実装していくと、所有権が既に無いなどでよく コンパイラに怒られる ❏ 所有権の問題解決の勘所を押さえる ❏ 値を参照するだけであれば、参照を渡す ❏ Clone トレイトを用いて値を複製する ❏ メモリコストはかかるが、そこまでシビアに意識する必要が無 ければこの方法で対応することが多い

Slide 31

Slide 31 text

ライフタイム ※ 今回は概略だけご説明します

Slide 32

Slide 32 text

ライフタイム ❏ ライフタイムとは、その参照が有効になるスコープのこと ❏ ライフタイムという仕組みによって、ダングリング参照 (解放済みの意 図しないデータ参照など) を回避することができる

Slide 33

Slide 33 text

❏ Rust コンパイラには、スコープを比較して全ての借用が有効で あるかを決定する借用チェッカーというものがあり、これのお かげでダングリング参照をコンパイル時に弾いている ライフタイム

Slide 34

Slide 34 text

❏ 下記のコードは、実行するまで x と y のどちらの参照が戻り値 の参照となるかわからない ❏ x と y のどちらのライフタイムが戻り値となるかコンパイラは わからないためエラーになる ライフタイム ~ 変数のスコープが切れない関数 ~

Slide 35

Slide 35 text

ライフタイム ~ 変数のスコープが切れない関数 ~

Slide 36

Slide 36 text

❏ 下記の用にライフタイム注釈をつけることで、コンパイラは x と y の短い方のライフタイムを適用するということを知ること ができ、コンパイルが通る ライフタイム注釈

Slide 37

Slide 37 text

ライフタイム注釈

Slide 38

Slide 38 text

どのようにライフタイムと向き合うか ❏ ライフタイムは正直難しい... が、なるべくライフタイム注釈を 利用しなくても済むような設計を心がける ❏ どうしてもライフタイムを意識して実装しなければならない場 所は限られてくる ❏ ⇒ 要するにブロック内で変数のスコープが完結しない場合 (関数で戻り値に参照を使う場合など) ❏ 基本的にはブロック内で変数を完結させるようにする ❏ できない場合は Clone で複製したり別の Struct を返すようにする

Slide 39

Slide 39 text

Rust 特有の概念でつまずく ~存在を認知して、コンパイラに怒られながら進める~

Slide 40

Slide 40 text

Web アプリケーション開発で つまずく

Slide 41

Slide 41 text

❏ Rust のライブラリ (Crate) 開発は活発ではあるが、比較的近年登場 した言語のため、デファクトスタンダードがわからず、ライブラリ選 定やテスティング手法で時間をかけることが多いと感じる ❏ オニオンアーキテクチャなどで DI をしたい場合、Java は Spring の 強力な DI の仕組みに乗っかればいいが、今回採用した Rust の Web フレームワークである axum には汎用的な DI がなかったため、DI の 仕組みを自作することに Web アプリケーション開発でつまずく ※ 時間の関係で詳しくはご説明できませんが、 別途公開する資料や、サンプルコードなどをご覧になってみてください!

Slide 42

Slide 42 text

Rust を触りたての頃の感想

Slide 43

Slide 43 text

Java が恋しい! Java なら簡単なのに! Result, Option, iterator … ライフタイム 所有権 借用 … DI の自作 ライブラリ選定 テスティング

Slide 44

Slide 44 text

はたして本当に Java のほうが簡単なのだろうか?

Slide 45

Slide 45 text

Java は Java で難しい部分がある

Slide 46

Slide 46 text

Java の難しいところ ~ コンテナ化例 ❏ 例えばコンテナ化をする際、Java では JVM という仕組みがあ るため以下のようなことを考慮する必要がある ● 起動時間を短くする工夫 ● コンテナサイズを小さくする工夫 ● コンテナ特有の JVM パラメータチューニング (GC どうするか、メモリ領域を それぞれどれくらい取ればいいか...など) ● JIT が十分にされていないとスループットが上がらないが、どれくらい暖気を すればいいのか... ※ Java でも GraalVM の Native Image を用いて実行可能ファイルを生成できるが 、機能が 制限されたりコンパイル時間がとても長かったりと商用利用するには課題も多い

Slide 47

Slide 47 text

Rust と Java のトレードオフ ❏ 実装の容易さという観点だけで見れば、Rust は Java よりも難 易度は高く、開発生産性は Java のほうが高いかもしれない ❏ しかし運用という観点も含めると、Java は JVM のチューニン グやコンテナ化の工夫などが必須で、この分野は体系だった文 献も少なく難易度は高い ❏ 加えて、LTS・ディストリビューション・サポート...など実際に運用する にあたっては考慮することが多い ❏ 一方 Rust はこのあたりを考慮する必要が Java に比べると圧倒 的に少ない

Slide 48

Slide 48 text

Rust と Java のトレードオフ ❏ パフォーマンスがある程度要求される場合での、実装と運用の 学習コストの個人的な体感 ❏ 「Rust は難しい」とよく言わ れている部分は実装難易度の部 分が多いのでは ❏ ちゃんと運用のことも考えると Java の学習コストは結構高い

Slide 49

Slide 49 text

Rust と Java のトレードオフ Rust Java 実行速度・起動速度のチューニング ◯ ✕ 運用の難易度 ◯ ✕ コンテナ化 ◯ ✕ 実装速度 ✕ ◯ ライブラリ・ツールの成熟度 ✕ ◯ 開発者の確保のしやすさ ✕ ◯ ❏ 個人的に感じる Rust と Java のトレードオフの関係の一例 ※ 対比のため ✕ としているが全く向いていないということではなく、それぞれの言語で日々改善が行われている

Slide 50

Slide 50 text

Java 開発者が Rust で 開発してみた ~まとめ~

Slide 51

Slide 51 text

❏ 色々つまづきながらではあるが、Rust でも商用レベルのバック エンドの Web アプリケーションは実装できる ❏ Rust 特有の概念の理解や、実装のコツなどの学習コストは確か に低くはないが、その学習コストに見合うだけのメリットは教 授できる ❏ 一部ツールなどで商用利用を開始しているが、Scala で実装された 同機能よりも早い実行速度を実現できている Rust でも Web アプリケーションは実装できた

Slide 52

Slide 52 text

❏ 学習コストに対してパフォーマンスの恩恵が大きい → Rust ❏ ある程度のパフォーマンスが求められ、安定したチームで開発・運用し、 学習の時間を確保できる場合は特に有効なのでは ❏ 今回のシステムでは上記を満たしていたので、Rust の技術選定は納得感 が高い ❏ (自分の場合) 下記の条件下では使い慣れている Java を選択す るかも ❏ チームが流動的 ❏ 期限がシビアかつパフォーマンスがそれほど求められない Rust と Java まとめ

Slide 53

Slide 53 text

学習方法・参考文献

Slide 54

Slide 54 text

出典: https://m.media-amazon.com/images/I/51Ks0DPW-oL.jpg 参考文献 ~ 本 出典: https://m.media-amazon.com/images/P/B07TQL7BB9.01._SCLZZZZZZZ_SX500_.jpg ● 原典が日本語で読みやすい ● Rust とはどういう言語か、CLI, 組み 込み, WebAP などの実装例を体系的 に学べる ● Rust のより詳細な言語仕様や実装方 法について学ぶことができる

Slide 55

Slide 55 text

参考文献 ~ Web ● Rust Playground: https://play.rust-lang.org/ ○ Web 上でコードを書いて簡単に実行できる ● Rust ツアー: https://tourofrust.com/chapter_1_ja.html ○ Web 上で基本文法を学べる ● 公式ドキュメント: https://doc.rust-jp.rs/book-ja/ ○ 困ったときにはまずここを見る ● Rust CookBook: https://uma0317.github.io/rust-cookbook-ja/about.html ○ Rust での色々な実装例が記されている ● awesome-rust: https://github.com/rust-unofficial/awesome-rust ○ 用途に応じてどの Crate を使ったらいいかを非公式にリスト化しているもの ○ ORM にはどんな Crate があるか? といった探し方ができる ● 元 CA の豊田さんによるハンズオン資料: https://speakerdeck.com/helloyuk13/di-1hui-rust-hands-on-2b580ec5-fdd8-4210-bc6b- ff0549a1945d ● 業務で作った Rust ハンズオン: https://github.com/shoichi1023/rust-web-handson

Slide 56

Slide 56 text

❏ コンパイラに教えてもらう ❏ rust-analyzer に教えてもらう ❏ IDE 上で Rust の入力補完や文法ミスなどをサポート 学習方法 ~ コンパイラと rust-analyzer ~ コンパイラや rust-analyzer が表示するメッセージはわかりやすく、時には解決策も提示してくれる

Slide 57

Slide 57 text

さいごに みなさんもぜひ Rust を使いましょう!! そして情報発信していただけると嬉しいです!!