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
osyo
October 27, 2020
Programming
380
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
200
AST を使って ActiveRecord の where の条件式をブロックで記述しよう
osyo
2
1.3k
Vim の開発環境自慢
osyo
5
3.1k
Use Macro all the time ~ マクロを使いまくろ ~ 感想戦
osyo
0
330
Use Macro all the time ~ マクロを使いまくろ ~ (English)
osyo
3
450
Use Macro all the time ~ マクロを使いまくろ ~ (日本語)
osyo
0
2.3k
月単位でイテレーションする
osyo
0
370
Ruby 3.0 で変わった private と attr_xxx
osyo
1
810
Ruby 2.0 から Ruby 3.0 を駆け足で振り返る
osyo
0
2.4k
Other Decks in Programming
See All in Programming
エンジニア向け会社紹介/Findy Company Profile
findyinc
6
350k
ローカルLLMを使ってB2Bサービスを作っていての学び
yaotti
0
210
A2UI という光を覗いてみる
satohjohn
1
150
肥大化するレガシーコードに立ち向かうためのインターフェース分離と依存の逆転 / JJUG CCC 2026 Spring
hirokunimaeta
0
610
トークンをケチるな、設計しろ:GitHub Copilotを賢く使うコンテキスト戦略
ochtum
0
160
代数的データ型って何が嬉しいの? #frontend_phpcon_do
kajitack
8
3.8k
PHPで使える日時の表現と、その知り方 #frontend_phpcon_do
o0h
PRO
0
260
1B+ /day規模のログを管理する技術
broadleaf
0
110
スマートグラスで並列バイブコーディング
hyshu
0
260
気圧・高度・GPSを記録&可視化するアプリ「Koudo」を作った話
hjmkth
1
320
さぁV100、メモリをお食べ・・・
nilpe
0
150
例外の正しい扱い方 そのエラー try-catchして大丈夫?
jinwatanabe
0
280
Featured
See All Featured
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
240
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
860
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
3.5k
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.5k
The Mindset for Success: Future Career Progression
greggifford
PRO
0
370
Building AI with AI
inesmontani
PRO
1
1.1k
The untapped power of vector embeddings
frankvandijk
2
1.8k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
200
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
950
Prompt Engineering for Job Search
mfonobong
0
350
A Tale of Four Properties
chriscoyier
163
24k
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
220
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
ご清聴 ご清聴 ありがとうございました ありがとうございました