$30 off During Our Annual Pro Sale. View Details »

満を持して始めるRust

 満を持して始めるRust

Developers Summit(デブサミ)
9-B-9 02/09 17:45 ~ 18:25
「満を持して始めるRust」kenkoooo

RustはC++の代替となることが期待されていることから、低レイヤ向け言語という印象を持っている方も多いかもしれません。しかし、Rust 1.0のリリースから7年ほど経ち、言語そのものだけでなく周辺のライブラリやツールも充実し、普段遣いのプログラミング言語として快適に開発できる環境が整っています。

本セッションでは、今日からRustで開発をスタートすることを目指し、Rustそのものの紹介だけでなく、実際の開発におけるコードの書き方や、estieでの導入事例をご紹介します。

estie | エスティ

February 09, 2023
Tweet

More Decks by estie | エスティ

Other Decks in Programming

Transcript

  1. @kenkoooo 1. ニート (自宅警備) 2. 国立情報学研究所 (アルゴリズム研究補佐) 3. リクルート (リアルタイム広告配信)

    4. SoundHound (車載 AI スピーカー) 5. Indeed (求人検索サービス) 6. estie (商業用不動産 SaaS )
  2. そもそもプログラミングが難しい! class Foo: def __init__(self, a): self.a = a def

    foo(self): self.a.append("Foo") class Bar: def __init__(self, a): self.a = a def bar(self): self.a.append("Bar") a = [] foo = Foo(a) bar = Bar(a) foo.foo() # a = ["Foo"] bar.bar() # a = ["Foo", "Bar"] • Foo: ◦ a を変数にとる ◦ a に要素を追加する • Bar: ◦ a を変数にとる ◦ a に要素を追加する
  3. そもそもプログラミングが難しい! class Foo: def __init__(self, a): self.a = a def

    foo(self): self.a.append("Foo") class Bar: def __init__(self, a): self.a = a def bar(self): self.a.append("Bar") a = [] foo = Foo(a) bar = Bar(a) foo.foo() # a = ["Foo"] bar.bar() # a = ["Foo", "Bar"] • Foo: ◦ a を変数にとる ◦ a に要素を追加する • Bar: ◦ a を変数にとる ◦ a に要素を追加する Rust ではコンパイルが通らない
  4. そもそもプログラミングが難しい! class Foo: def __init__(self, a): self.a = a def

    foo(self): self.a.append("Foo") class Bar: def __init__(self, a): self.a = a def bar(self): self.a.append("Bar") a = [] foo = Foo(a) bar = Bar(a) foo.foo() # a = ["Foo"] bar.bar() # a = ["Foo", "Bar"] • Foo は a を更新する • Bar も a を更新する → メンバ変数が勝手に更新される
  5. そもそもプログラミングが難しい! class Foo: def __init__(self, a): self.a = a def

    foo(self): self.a.append("Foo") class Bar: def __init__(self, a): self.a = a def bar(self): self.a.append("Bar") a = [] foo = Foo(a) bar = Bar(a) foo.foo() # a = ["Foo"] bar.bar() # a = ["Foo", "Bar"] • Foo は a を更新する • Bar も a を更新する → メンバ変数が勝手に更新される Foo も Bar も a も、 どのタイミングで更新されるか、 把握する必要がある。
  6. コンパイラが強い • Rust ではコンパイラが何とかしてくれる • コンパイル時に弾く → 実行時は安心 • "

    所有権 " によって解決 • 「一生コンパイルが通らない」 • コンパイラに概念を教えてもらえる
  7. Rust では Rust では "?" で早期 return できる "?" をつけた

    Result が Err なら、そのまま return let result = read_file()?;
  8. Result まとめ • 失敗しうる関数は Result を返す ◦ エラーハンドリングを見落とさない • "?"

    で早期 return できる ◦ if err != nil: からの解放 Result 以外にも便利な機能がいっぱい!
  9. Rust を始める Web フレームワーク "actix-web" 他の言語と同じ感覚で作れる use actix_web::{get, web, Responder};

    #[get("/hello/{name}")] async fn greet(name: web::Path<String>) -> impl Responder { format!("Hello {name}!") }
  10. Rust を始める フロントエンド "yew" • ほぼ React • Wasm に変換される

    use yew::prelude::*; #[function_component] fn App() -> Html { let counter = use_state(|| 0); let onclick = { let counter = counter.clone(); move |_| { let value = *counter + 1; counter.set(value); } }; html! { <div> <button {onclick}>{ "+1" }</button> <p>{ *counter }</p> </div> } } fn main() { yew::Renderer::<App>::new().render(); }
  11. estie での Rust 選定理由 • エラー処理・ Null 処理に強い ◦ Result

    / Option で型レベルでチェック ◦ 本番 try-catch 忘れ・ NullPointerException 回避 ◦ 人間が気をつける必要なし • コンパイラが厳しい ◦ チーム開発でコードの品質を担保 • 豊富な公式開発支援ツール ◦ clippy: Linter ◦ rust-analyzer: エディタを Rust IDE 化する
  12. estie の Rust 開発者 • estie で初めて Rust に触るという人が多い ◦

    前々から興味があった ◦ たまたま配属先が Rust を使ってた • バックグラウンド様々 ◦ JavaScript などフロントエンド ◦ Ruby on Rails など動的型付け言語 ◦ C++ (競技プログラマ)
  13. estie の Rust 入門 • Rust 研修なし • ハマるポイントが人それぞれ •

    稼働中のサービス ◦ 動かしながら学ぶ • ペアプロ・モブプロ • コードレビュー
  14. Result / Option • Result ◦ 失敗しうる関数を try-catch しない ◦

    戻り値が成功 or 失敗の情報を持つ • Option ◦ nullable な値 ◦ 型レベルで定義 ◦ null check 忘れを防ぐ
  15. マクロ • コンパイル時にコードを生成する #[derive(Clone)] struct A { x: i64, s:

    String, } struct A { x: i64, s: String, } impl Clone for A { fn clone(&self) -> A { A { x: Clone::clone(&self.x), s: Clone::clone(&self.s), } } } マクロ展開
  16. Rust に入門してみて • 「目が慣れたら分かる」 ◦ "?" とかは最初は見慣れない • 「 Result

    / Option は慣れるまで難しい」 ◦ 関数型言語の経験があると違うかも • 「オブジェクト指向の考え方は通用する」 ◦ 「継承」ができないくらい • 「難しい印象を持っていたが、そうでもない」 ◦ 直感的に書ける ◦ 色々な書き方があるので、動くものは書ける