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.6k
全員アーキテクトで挑む、 巨大で高密度なドメインの紐解き方
agatan
9
24k
チームで開発し事業を加速するための"良い"設計の考え方 @ サポーターズCoLab 2025-07-08
agatan
2
710
医療系スタートアップが経験した 認知負荷問題の症状分析と処方箋 チーム分割による認知負荷の軽減 / Cognitive Load Busters
agatan
2
640
専門性の高い領域をいかに開発し、 テストするか / How to test and develop complicated systems with Domain Experts!
agatan
3
940
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
freeeにおけるEvalsの実践例の紹介
freee
PRO
0
120
PHP に部分適用が来るぞ!……ところで何それ?おいしいの? #phpcon / phpcon-2026
shogogg
0
690
生成AI導入の「期待外れ」を乗り越える ー 開発フロー改革が目指す、真の組織変革
starfish719
0
4.7k
ソフトウェア設計に溶けるインフラ ― AWS CDK のインフラ認識論
konokenj
3
800
Building a Meta Ray-Ban display app
akkeylab
0
160
バグを直したら useEffect が消えた
colorful12
3
610
仕様駆動開発の消費期限
watany
20
8.6k
「人を評価する AI」の設計と実装
ryoyanara
0
210
生成AIで帳票OCRが「簡単に」作れる時代になった?
kon_shou
0
1.1k
Claude Code全社展開のためにやったことn選~プラグイン302個・コミッター271人を支えるために~
kenchan
5
1.6k
リアルな遅延を測る仕様
kota_yata
1
120
SlackアプリとLambdaの 連携を構築した話
pawn_4_s
1
120
Featured
See All Featured
GitHub's CSS Performance
jonrohan
1033
470k
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
230
Typedesign – Prime Four
hannesfritz
42
3.1k
Everyday Curiosity
cassininazir
0
290
Game over? The fight for quality and originality in the time of robots
wayneb77
1
240
It's Worth the Effort
3n
188
29k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
1.8k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
53k
How to build a perfect <img>
jonoalderson
1
5.9k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
232
55k
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
64
56k
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 的なことをしてもそんなに辛く ない 型以外にもエラーメッセージは本当に読みやすくて 最高