Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Rust の LT 会! 2016/11/21
Search
Agata Naomichi
November 21, 2016
Programming
2.5k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Rust の LT 会! 2016/11/21
Agata Naomichi
November 21, 2016
More Decks by Agata Naomichi
See All by Agata Naomichi
Why Kotlin? 電子カルテを Kotlin で開発する理由 / Why Kotlin? at Henry
agatan
2
9.5k
全員アーキテクトで挑む、 巨大で高密度なドメインの紐解き方
agatan
9
24k
チームで開発し事業を加速するための"良い"設計の考え方 @ サポーターズCoLab 2025-07-08
agatan
2
700
医療系スタートアップが経験した 認知負荷問題の症状分析と処方箋 チーム分割による認知負荷の軽減 / Cognitive Load Busters
agatan
2
630
専門性の高い領域をいかに開発し、 テストするか / How to test and develop complicated systems with Domain Experts!
agatan
3
930
Henry のサーバーサイドアーキテクチャ 狙いと課題 2022.08.25 / Server-Side Architecture at Henry, Inc.
agatan
3
6.1k
The Web Conference 2020 - Participation Report
agatan
1
760
○○2vec 再考
agatan
1
4.7k
Improving "People You May Know" on Directed Social Graph
agatan
4
2.8k
Other Decks in Programming
See All in Programming
1年で人数1.5倍、PR数5.5倍増。 品質とアウトカムはどうなったか、 何が効いたか
ike002jp
0
140
使用 Meilisearch 建立新聞搜尋工具
johnroyer
0
160
PHP Application における Kubernetes 内 gRPC 通信
ganchiku
0
520
AIキャラアプリkaiwaの低遅延音声通話基盤をどう作ったか - AWS Gravitonで支える低遅延・低コストAI Agent基盤
mogamit
0
180
AI駆動開発を妨げる技術的負債の解消アプローチ / ai-refactoring-approach
minodriven
17
9.2k
OSINT for SRE: 学術論文とポストモーテムから探る システム障害の共通パターン / SRE NEXT 2026
tomoyk
1
4k
ITヒヤリハットを整理してみた ~ライフサイクルと原因から考える再発防止策~
koukimiura
1
110
【やさしく解説 設計編 #0】DDDのコード、読めるのに分からない人へ
panda728
PRO
2
270
分散システム、なんですぐ死んでしまうん?耐障害性を高めたいあなたのためのレジリエンスパターン入門
mshibuya
7
6.6k
なぜ型を書くのか? TSKaigi2026で改めて考える #tskaigi_smarthr
kajitack
0
390
任せる範囲はこう広がった / How the Scope of AI Delegation Has Expanded
nrslib
1
270
Built Our Own Background Agent at LayerX #aidevex_findy
layerx
PRO
5
2k
Featured
See All Featured
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.3k
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
460
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
1
2.8k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
610
Fashionably flexible responsive web design (full day workshop)
malarkey
408
67k
The Invisible Side of Design
smashingmag
301
52k
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
220
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
280
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
3.9k
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
810
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
1
3.7k
Transcript
ジェネリクスと 静的ディスパッチと エラーメッセージ 2016/11/21 RUST の LT 会!
ABOUT ME agatan Twitter: GitHub: 趣味は言語処理系/ コンパイラいじり 自作言語の妄想をするのがすきです システムプログラミング系の研究室にいます @agatan_
http://github.com/agatan/
RUST のジェネリクス 一つのコードで複数の型に対応する / trait 制約を付けられる 使うときは具体的な型をいれる / そして型推論 fn
hello<T: Display>(x: T) -> String { format!("Hello {}", x) }
どうコンパイルされるか Rust のジェネリクスは monomorphization によってコ ンパイルされる インスタンス化されるたびに専用の関数をつくる fn snd<T, U>(x:
(T, U)) -> U { x.1 } let a: (i64, i64) = (0, 1); snd(a); // => 1 let b: (Vec<i32>, Option<u64>) = (vec![], None); snd(b); // => None この例では と がインスタンス化されている let a: (i64, i64) = (0, 1); snd_i64_i64(a); // <= 専用 関数 呼 let b: (Vec<i32>, Option<u64>) = (vec![], None); snd_vec_i32_option_u64(b); // <= 専用 関数 呼 こんな感じにコンパイルされる
ジェネリクスとトレイト trait Greet { fn greet(&self) -> String; } impl
Greet for String { fn greet(&self) -> String { format!("Hello, I'm {}", self) } } impl Greet for i64 { fn greet(&self) -> String { format!("Hello, I'm No.{}", self) } } ジェネリクスにトレイトによる制約がつけられる fn conversation<T: Greet, U: Greet>(t: T, u: U) { println!("T => {}", t.greet()); println!("U => {}", u.greet()); } monomorphization によってコンパイルされる の部分はどうなる?
静的ディスパッチ 専用の関数はどうコン パイルされるか コンパイル時にどの関数を呼ぶかすべてわかっている => 静的ディスパッチ の っぽい fn conversation_i64_String(t:
i64, u: String) { println!("T => {}", t.greet()); // => greet i64::greet println!("U => {}", u.greet()); // => greet String::greet }
静的ディスパッチ 利点 インライン展開できる!! 関数を動的に探す必要がない!!( ただの関数呼び 出し) 欠点 バイナリが大きくなる... 分割コンパイルできない
動的ディスパッチ どの関数を呼ぶか実行時に決定する の仮想関数 class A { public virtual void greet()
{ std::cout << "Hello, I'm A\n"; } } class B: public A { public virtual void greet() override { std::cout << "Hello, I'm B\n" } void greet(A const& a) { a.greet(); // A::greet? B::greet? } 典型的には仮想関数のテーブルをオブジェクトに紐付 けておく 実行時に対象オブジェクトの に対応する関数 ポインタを探す
動的ディスパッチ Rust ではトレイトオブジェクトを使う / = 「 を満たす何か」のベ クタ とはかけない 利点
バイナリサイズの節約 分割コンパイルを諦める必要がない 欠点 実行時コストがかかる
型が爆発する monomorphization を進めていくと,型が爆発する 自前のちょっとしたパーサコンビネータの例 let mut parser = char('"') .and(take_while(|x:
&char| *x != '"')) .and(char('"')) .map(|((_, s), _)| s); の型は Map< And< And< Char<StrInput<'a>>, TakeWhile<[closure@src/main.rs:253:25: 253:45], StrInput<'a>, String> >, Char<StrInput<'a>> >, [closure@src/main.rs:255:14: 255:29] >
EXPRESSION TEMPLATE 式を型で表す! c.f. Boost.Spirit (C++ のパーサコンビネータ) Rust には型推論があるので,型の複雑さはほとんど気 にならない!
関数定義のときは返り値の型を明示しなくてはならな くて若干つらい... この辺は読みやすさとのトレードオフ Rust のコンパイルエラーはわかりやすいので expression template も(そこまで)辛くない!!
わざとエラーを起こしてみる としてコンパイルエラーを起こ してみると => 読みやすい!! 良い感じに詳細が省かれた型名を表示してくれる どういう基準でやっているのかはよくわからない...
もっとエラーを起こしてみる とやってみる までは合っている.3 つ目の が間違っている. => 本当に読みやすい!!!!
まとめ Rust のジェネリクスは静的に色々解決する 動的にもできる ( トレイトオブジェクト ) ジェネリクスしまくると型が爆発する!! Rust の型推論は強力なので,ほとんど気にならない
型が合わなくなってもエラーメッセージが本当にわか りやすい!!! expression template 的なことをしてもそんなに辛く ない 型以外にもエラーメッセージは本当に読みやすくて 最高