Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Java developer introduced to Rust-ADC2022

Takaichi00
November 29, 2022

Java developer introduced to Rust-ADC2022

Takaichi00

November 29, 2022
Tweet

More Decks by Takaichi00

Other Decks in Technology

Transcript

  1. Java 開発者が Rust に入門してみた #ADC2022 髙市 智章 (Tomoaki Takaichi) Nov,

    25, 2022 AItech Developer Conference 2022
  2. 自己紹介 @Takaichi00 tomoaki.takaichi.5 ・髙市 智章(タカイチ トモアキ) ・2022/05 CA 入社 ・エレベーターサイネージ

    ・Rust / Java でのシステム開発 共著: クリーンなコードへの SonarQube即効活用術 www.amazon.co.jp/dp/B086ML43DH
  3. 発表の流れ

  4. ❏ 主に Java を使ってきた自分にとって、Rust は今までにない概 念が多く、つまずいたポイントがいくつもあった (今でもつまず き続けている) ❏ Rust

    を始める6ヶ月前の自分に対して、「Rust はこんな言語で すよ」「Rust と Java はこんな違いがありますよ」と伝えるよ うな発表をコンセプトにし、これから Rust を触ってみようとい う方の参考になれば 発表をしようと思ったか
  5. Rust 言語とは

  6. ❏ 2015年に正式リリース ❏ 静的型付け・コンパイラ言語 ❏ システムプログラミング言語 ❏ C / C++

    に匹敵する速度を実現し、OS, 組み込み, ブラウザなど低 レイヤーを目的に作られた ❏ C 言語に加えて、Linux カーネルの開発向けプログラミング言語 として採用される (Linux 6.1 から) Rust 言語
  7. Rust 言語 ❏ しかしモダンな言語機能も搭載されており、高レイヤーまであつかう ことができる ❏ 2019年の Rust Survey によると、利用事例が一番多いのは

    ”Web バックエンドアプリケーション” となっている 出典: https://blog.rust-lang.org/2020/04/17/Rust-survey-2019.html
  8. Rust 言語の特徴 ❏ GC (ガベージコレクション) がない ❏ にも関わらず、メモリ安全+並行処理安全である ❏ ゼロコスト抽象化

    ❏ プログラミング言語が持つ抽象化 (ポリモーフィズム・高階関数 など) の 機能をきる限り実行時ではなくコンパイル時に行うことで、実行速度の低 下やメモリ使用量の増加を防ぐことができる ❏ 独自の仮想マシン (JVM など) を持たず、直接機械語にコンパ イルされる
  9. (軽く) Java 言語とは

  10. Java 言語とは ❏ 1996年に最初のバージョンがリリースされる (Rust 誕生の19 年前!) ❏ 静的ページが主流だった当時、Java Applet

    を使えば簡単に動的ページが作れると いうところから人気を博す ❏ バイトコードにコンパイル → JVM がインタプリタ実行 ❏ プラットフォームに依存しないプログラム開発 ❏ GC / JIT コンパイラ がある ❏ エンタープライズシステムなどの利用例が豊富
  11. ここまでの説明を聞いた 当時の感想

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

    でも、商用システムで使って大丈夫なの...?
  13. Rust で Web バックエンド アプリケーションを開発してみた

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

  15. 基本文法でつまずく

  16. Rust と関数型言語 ❏ Rust は関数型言語ではないが、関数型言語由来の文法や言語機 能が多く採用されている ❏ これからお話する Result, Option,

    Iterator は関数型の機能 が 元となっているが、慣れるまではコードを見ても何が起きてい るのかイメージしづらかった
  17. Result ・Option 型 ❏ Rust には Go と同様に例外の機構はない ❏ エラーハンドリングには

    Result<T, E> という列挙型 (関数型の Either が ベース) を使うか、パニックを起こして処理を強制終了させる方法がある ❏ 想定内のエラーであれば Result の Err を返すのが基本 ❏ Rust には null 機能が存在しない ❏ これは安全性向上のための意図的な設計 ❏ 存在するかしないかの値を表現したいときは Option という列挙型を利用 する
  18. Result 型・Option 型と match 式 ❏ Rust にはマッチしたパターンに応じてコードを実行させてくれ る強力な match

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

    式以外にも様々なシンタックス シュガーを用いてハンドリングをすることができる ❏ しかし使いこなすまでには時間がかかった (今もなお苦戦中) ? 演算子
  20. Result + Option と Iterator の組み合わせ ❏ Rust には Java

    でいう Stream API のような、Iterator という Trait が提供されている ❏ Iterator と Option, Result 型などが組み合わさった処理は自分で書 けるようになるまで更に時間がかかった
  21. 基本文法でつまずく ~関数型に慣れる必要がある~

  22. Rust 特有の概念でつまずく

  23. 「GC がない」 かつ 「メモリ安全」 ❏ Rust には GC がないため、メモリ安全のコードを自前で実装し なければならない

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

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

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

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

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

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

  30. どのように所有権と向き合うか ❏ 何も意識せずに実装していくと、所有権が既に無いなどでよく コンパイラに怒られる ❏ 所有権の問題解決の勘所を押さえる ❏ 値を参照するだけであれば、参照を渡す ❏ Clone

    トレイトを用いて値を複製する ❏ メモリコストはかかるが、そこまでシビアに意識する必要が無 ければこの方法で対応することが多い
  31. ライフタイム ※ 今回は概略だけご説明します

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

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

  34. ❏ 下記のコードは、実行するまで x と y のどちらの参照が戻り値 の参照となるかわからない ❏ x と

    y のどちらのライフタイムが戻り値となるかコンパイラは わからないためエラーになる ライフタイム ~ 変数のスコープが切れない関数 ~
  35. ライフタイム ~ 変数のスコープが切れない関数 ~

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

  37. ライフタイム注釈

  38. どのようにライフタイムと向き合うか ❏ ライフタイムは正直難しい... が、なるべくライフタイム注釈を 利用しなくても済むような設計を心がける ❏ どうしてもライフタイムを意識して実装しなければならない場 所は限られてくる ❏ ⇒

    要するにブロック内で変数のスコープが完結しない場合 (関数で戻り値に参照を使う場合など) ❏ 基本的にはブロック内で変数を完結させるようにする ❏ できない場合は Clone で複製したり別の Struct を返すようにする
  39. Rust 特有の概念でつまずく ~存在を認知して、コンパイラに怒られながら進める~

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

  41. ❏ Rust のライブラリ (Crate) 開発は活発ではあるが、比較的近年登場 した言語のため、デファクトスタンダードがわからず、ライブラリ選 定やテスティング手法で時間をかけることが多いと感じる ❏ オニオンアーキテクチャなどで DI

    をしたい場合、Java は Spring の 強力な DI の仕組みに乗っかればいいが、今回採用した Rust の Web フレームワークである axum には汎用的な DI がなかったため、DI の 仕組みを自作することに Web アプリケーション開発でつまずく ※ 時間の関係で詳しくはご説明できませんが、 別途公開する資料や、サンプルコードなどをご覧になってみてください!
  42. Rust を触りたての頃の感想

  43. Java が恋しい! Java なら簡単なのに! Result, Option, iterator … ライフタイム 所有権

    借用 … DI の自作 ライブラリ選定 テスティング
  44. はたして本当に Java のほうが簡単なのだろうか?

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

  46. Java の難しいところ ~ コンテナ化例 ❏ 例えばコンテナ化をする際、Java では JVM という仕組みがあ るため以下のようなことを考慮する必要がある

    • 起動時間を短くする工夫 • コンテナサイズを小さくする工夫 • コンテナ特有の JVM パラメータチューニング (GC どうするか、メモリ領域を それぞれどれくらい取ればいいか...など) • JIT が十分にされていないとスループットが上がらないが、どれくらい暖気を すればいいのか... ※ Java でも GraalVM の Native Image を用いて実行可能ファイルを生成できるが 、機能が 制限されたりコンパイル時間がとても長かったりと商用利用するには課題も多い
  47. Rust と Java のトレードオフ ❏ 実装の容易さという観点だけで見れば、Rust は Java よりも難 易度は高く、開発生産性は

    Java のほうが高いかもしれない ❏ しかし運用という観点も含めると、Java は JVM のチューニン グやコンテナ化の工夫などが必須で、この分野は体系だった文 献も少なく難易度は高い ❏ 加えて、LTS・ディストリビューション・サポート...など実際に運用する にあたっては考慮することが多い ❏ 一方 Rust はこのあたりを考慮する必要が Java に比べると圧倒 的に少ない
  48. Rust と Java のトレードオフ ❏ パフォーマンスがある程度要求される場合での、実装と運用の 学習コストの個人的な体感 ❏ 「Rust は難しい」とよく言わ

    れている部分は実装難易度の部 分が多いのでは ❏ ちゃんと運用のことも考えると Java の学習コストは結構高い
  49. Rust と Java のトレードオフ Rust Java 実行速度・起動速度のチューニング ◯ ✕ 運用の難易度

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

  51. ❏ 色々つまづきながらではあるが、Rust でも商用レベルのバック エンドの Web アプリケーションは実装できる ❏ Rust 特有の概念の理解や、実装のコツなどの学習コストは確か に低くはないが、その学習コストに見合うだけのメリットは教

    授できる ❏ 一部ツールなどで商用利用を開始しているが、Scala で実装された 同機能よりも早い実行速度を実現できている Rust でも Web アプリケーションは実装できた
  52. ❏ 学習コストに対してパフォーマンスの恩恵が大きい → Rust ❏ ある程度のパフォーマンスが求められ、安定したチームで開発・運用し、 学習の時間を確保できる場合は特に有効なのでは ❏ 今回のシステムでは上記を満たしていたので、Rust の技術選定は納得感

    が高い ❏ (自分の場合) 下記の条件下では使い慣れている Java を選択す るかも ❏ チームが流動的 ❏ 期限がシビアかつパフォーマンスがそれほど求められない Rust と Java まとめ
  53. 学習方法・参考文献

  54. 出典: 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 のより詳細な言語仕様や実装方 法について学ぶことができる
  55. 参考文献 ~ 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
  56. ❏ コンパイラに教えてもらう ❏ rust-analyzer に教えてもらう ❏ IDE 上で Rust の入力補完や文法ミスなどをサポート

    学習方法 ~ コンパイラと rust-analyzer ~ コンパイラや rust-analyzer が表示するメッセージはわかりやすく、時には解決策も提示してくれる
  57. さいごに みなさんもぜひ Rust を使いましょう!! そして情報発信していただけると嬉しいです!!