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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
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.4k
全員アーキテクトで挑む、 巨大で高密度なドメインの紐解き方
agatan
8
23k
チームで開発し事業を加速するための"良い"設計の考え方 @ サポーターズ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
910
Henry のサーバーサイドアーキテクチャ 狙いと課題 2022.08.25 / Server-Side Architecture at Henry, Inc.
agatan
3
6k
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
正しくソフトウェアを作る、前提を疑うための認知の視点 / doubt-premise
minodriven
20
6.5k
セキュリティの専門家じゃなくてもできる。「セキュリティ意識」をアップデートして サプライチェーン攻撃への耐性を高めよう。
tk3fftk
5
710
脅威をエンジニアリングの糧にして――現場編 / Turning Threats into Engineering Fuel — Field Edition
nrslib
0
270
JJUG CCC 2026 Spring: JSpecify で実現する Kotlin フレンドリーな Java API 設計
ternbusty
1
160
Composerを使ったサプライチェーン攻撃の様子を眺めてみる #phpstudy
o0h
PRO
2
240
ローカルLLMでどこまでコードが書けるか -拡張版 / How much code can be written on a local LLM Extended
kishida
2
1.2k
Copilot CLI の継戦能力を高める コンテキスト管理
nozomutu
1
1.2k
生成AI時代にこそ効くGo | Why Go Works in the Age of Generative AI
mom0tomo
8
3.2k
依存関係から依存物へ―Dependencyという言葉の歴史をひも解く
j_lee
0
110
Vite+ Unified Toolchain for the Web
naokihaba
0
270
Javaの型とAI時代に型が大事な理由 / java types and type in AI era
kishida
2
120
Skillsは効率化、Agentsは"自分の拡張"——Builder時代のエージェント編成(CC Night 2026)
wemra
1
120
Featured
See All Featured
Information Architects: The Missing Link in Design Systems
soysaucechin
0
970
Statistics for Hackers
jakevdp
799
230k
Amusing Abliteration
ianozsvald
1
200
Context Engineering - Making Every Token Count
addyosmani
9
960
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
570
The Invisible Side of Design
smashingmag
302
52k
Rebuilding a faster, lazier Slack
samanthasiow
85
9.5k
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
130
Are puppies a ranking factor?
jonoalderson
1
3.5k
The Art of Programming - Codeland 2020
erikaheidi
57
14k
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
62
54k
Optimizing for Happiness
mojombo
378
71k
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 的なことをしてもそんなに辛く ない 型以外にもエラーメッセージは本当に読みやすくて 最高