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 のマクロについて調べてみた
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
osyo
October 27, 2020
Programming
390
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Rust のマクロについて調べてみた
osyo
October 27, 2020
More Decks by osyo
See All by osyo
5分で話せる Ruby 3.1
osyo
0
210
AST を使って ActiveRecord の where の条件式をブロックで記述しよう
osyo
2
1.3k
Vim の開発環境自慢
osyo
5
3.1k
Use Macro all the time ~ マクロを使いまくろ ~ 感想戦
osyo
0
340
Use Macro all the time ~ マクロを使いまくろ ~ (English)
osyo
3
470
Use Macro all the time ~ マクロを使いまくろ ~ (日本語)
osyo
0
2.4k
月単位でイテレーションする
osyo
0
380
Ruby 3.0 で変わった private と attr_xxx
osyo
1
830
Ruby 2.0 から Ruby 3.0 を駆け足で振り返る
osyo
0
2.5k
Other Decks in Programming
See All in Programming
レビュー履歴をAIに食わせて、 Compose移行を加速するs
shihochan
0
230
片田舎のおっさん、 Swift Buildのダイアモンド問題解決の不具合修正PRを出すが、解決方法がキャッシュをしないようにすることであり、ビルド時間が伸びると言われてマージされないので高速化もする/swiftbuild
yimajo
0
310
プロポーザルを書いてもらう
pvcresin
0
590
Go 1.27 における memory allocation の高速化
andpad
0
340
関東Kaggler会_NVIDIA_Nemotron_コンペ_振り返り
rick_ds
0
730
夏だ!祭りだ!祭りとはドメインモデリングでは?
ryugen04
0
440
React本体のコードリーディング
high_g_engineer
1
160
Loosening the Reins: Go Generics Get More Flexible
kuro_kurorrr
0
350
FastAPI の並行処理モデルを完全に理解する
hoto17296
8
3.2k
仕様駆動開発の消費期限
watany
20
9.1k
Claude Code全社展開のためにやったことn選~プラグイン302個・コミッター271人を支えるために~
kenchan
5
1.8k
Dockerfile CMD for Node.js
grazie1999
0
140
Featured
See All Featured
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.3k
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
0
490
Context Engineering - Making Every Token Count
addyosmani
9
1.1k
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
1.1k
Darren the Foodie - Storyboard
khoart
PRO
3
3.8k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
Why Our Code Smells
bkeepers
PRO
340
58k
Mobile First: as difficult as doing things right
swwweet
225
10k
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
510
Testing 201, or: Great Expectations
jmmastey
46
8.2k
VelocityConf: Rendering Performance Case Studies
addyosmani
331
25k
The Cult of Friendly URLs
andyhume
79
7k
Transcript
Rust LT 会@ オンライン Rust LT 会@ オンライン Rust のマクロについて調べてみた
Rust のマクロについて調べてみた
⾃⼰紹介 ⾃⼰紹介 名前:osyo Twitter : github : ブログ : 元
C++er の現 Rails エンジニア 趣味で Ruby にパッチを投げたりしてる Rust 歴は1 ⽇ 昔 struct + trait でコンパイル時処理で遊んだことはある コンパイル時に階乗を⾏おうとしたりとか… @pink_bangbi osyo-manga Secret Garden(Instrumental) https://osyo-manga.github.io/slide-shinjukurb-58-rust/#/
Rust のマクロについて調べてみた Rust のマクロについて調べてみた
マクロとは マクロとは ソースコード中に繰り返し登場する特定の記述を、別の(短い)記 述に置き換えることができる機能をマクロという。 C / C++ ではプリプロセッサでプリプロセス時に機械的にコードを置 換する機能 Rust
でも同等の機能があるが C / C++ よりもより強⼒な機能になって いる 単純な置換ではなくて構⽂⾃体を拡張できる 構⽂⽊レベルでの拡張ができる(らしい #define PI 3.14 #define PLUS(a, b) a + b auto f = PI + PI; // auto f = 3.14 + 3.14 auto n = PLUS(1, 2) * 3 // auto n = 1 + 2 * 3
簡単な使い⽅ 簡単な使い⽅ macro_rules! 名前 {} でマクロを定義する事ができる ( 引数) => {
展開後のコード } でマクロ本体を記述する // マクロを定義する // hello がマクロ名になる macro_rules! hello { () => { println!("Hello!"); }; } fn main() { // 定義したマクロを呼び出す // hello!() のように ! を付けて関数っぽい呼び出しを⾏う hello!(); // println!("Hello!"); に置き換わる // () ではなくて [] や {} で呼び出すことができる hello![]; // {} の場合は ; がなくてもいいらしい hello!{} }
パターンを定義する パターンを定義する ( パターン) => { ... } で呼び出し元から渡された値を元に処理を分岐す ることができる
macro_rules! animal { // 引数の値で処理を切り分ける (cat) => { " にゃーん" }; (dog) => { " わーん" }; // 再帰的にマクロを呼び出すこともできる (cat and dog) => { animal!(cat).to_string() + " and " + animal! (dog) }; (cat -> dog) => { animal!(cat).to_string() + " to " + animal!(dog) }; } fn main() { // 引数の⽂字列によって呼び出されるマクロの処理が切り替わる println!("{}", animal!(cat)); // output: にゃーん println!("{}", animal!(dog)); // output: わーん println!("{}", animal!(cat and dog)); // output: にゃーん and わーん println!("{}", animal!(cat -> dog)); // output: にゃーん to わーん }
パターンを変数で受け取る パターンを変数で受け取る メタ変数と呼ばれるもので { 変数名: フラグメント指定⼦} で値を受け 取ることができる macro_rules! plus
{ // $a と $b で引数の値を受け取る // expr は『式を受け取る』という意味 // expr はフラグメント指定⼦と呼ばれる ($a: expr, $b: expr) => { $a + $b }; } macro_rules! calc { // 演算⼦も受け取る事ができる ($a: expr, $op: tt, $b: expr) => { $a $op $b }; } fn main() { println!("{}", plus!(1, 2)); // output: 3 println!("{}", plus!(1, 2 * 3)); // output: 7 println!("{}", calc!(1, -, 2)); // output: -1 }
デバッグ⽤のマクロをつくってみる デバッグ⽤のマクロをつくってみる 式とその結果の両⽅を出⼒するマクロを定義する // 式を受け取ってその式の⽂字列と結果を表⽰する macro_rules! debug { // stringify!
で受け取った値を⽂字列に変換できる ($expr: expr) => { println!("{} => {}", stringify!($expr), $expr) } } fn main() { let a = 42; debug!(1 + 2); // output: 1 + 2 => 3 debug!(a + 3); // output: a + 3 => 45 debug!(a.to_string() + "homu"); // a.to_string() + "homu" => 42homu }
マクロのスコープ マクロのスコープ マクロ内のスコープは独⽴しているので変数は外から参照できない macro_rules! test { // マクロ内のスコープは独⽴していて変数は外から参照できない () =>
{ let a = 42; println!("{}", a); }; } fn main() { test!(); // error[E0425]: cannot find value `a` in this scope a; }
マクロの優先順位( 評価順) マクロの優先順位( 評価順) マクロが先に評価される #define test 1 + 2
// 1 + 2 * 3 と展開される test * 3 // 7 macro_rules! test { () => { 1 + 2 }; } fn main() { // (1 + 2) * 3 が評価される println!("{}", test!() * 3); // output: 9 }
まとめ まとめ C / C++ と⽐べて Rust のマクロはかなり強⼒に⾒える この強⼒なマクロを Ruby
で実装したい… まだまだおもしろい使い⽅があると思うので今後も調べていきたい このあたりの話を普段から Rust を使っている⼈からいろいろと 聞いてみたい 実際のユースケースなどなど そもそも Rust のマクロの仕組みが(コンパイラや構⽂レベルで)わ かってないのでそのあたりを今後は理解していきたい
資料 資料 Rust の全マクロ種別が分かったつもりになれる話! / rust-all-kinds-of- macro ためしておぼえる Rust のマクロ
- Qiita Rust のマクロを覚える - Qiita マクロクラブ Rust ⽀部 | κeen のHappy Hacκing Blog
ご清聴 ご清聴 ありがとうございました ありがとうございました