34.rust宏.txt
生活随笔
收集整理的這篇文章主要介紹了
34.rust宏.txt
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
/*更多請看:
http://blog.hubwiz.com/2020/01/30/rust-macro/
https://github.com/rooat/RustLearn/blob/master/src/appendix-04-macros.md
https://rustcc.gitbooks.io/rustprimer/content/macro/macro.html
https://rust-by-example.budshome.com/macros.html定義:Rust宏讓你可以發(fā)明自己的語法,編寫出可以自行展開的代碼,也就是我們通常所說的元編程,你甚至可以用Rust宏來創(chuàng)作自己的DSL。從根本上來說,宏是一種為寫其他代碼而寫代碼的方式,即所謂的元編程運作機制:首先匹配宏規(guī)則中定義的模式,然后將匹配 結果綁定到變量,最后展開變量替換后的代碼。調用方式:另外從形式上看,與函數(shù)調用的另一個區(qū)別是參數(shù)可以用圓括號(())、花括號({})、方括號([])中的任意一種括起來,比如這行也可以寫成 println!["Hello, world!"] 或 println!{"Hello, world!"},不過對于 Rust 內置的宏都有約定俗成的括號,比如 vec! 用方括號,assert_eq! 用圓括號宏的分類:
聲明式宏( declarative macro )來進行元編程(metaprogramming)
過程式宏( procedural macro )來自定義 derive traits() => {}看起來很神秘,因為它不是標準的rust語法,是macro_rules! 這個宏自己發(fā)明的,用來表示一條宏規(guī)則,=>左邊是匹配模式,右邊是 等待展開的代碼rust 有哪些自帶宏?
源文件 std/src/macros.rs
panic print println eprint eprintln dbg assert_approx_eq debug_assert debug_assert_eq debug_assert_ne matches r#try write writeln unreachable unimplemented todo compile_error format_args format_args_nl env option_env concat_idents concat line column file stringify include_str include_bytes
module_path cfg include assert asm llvm_asm global_asm log_syntax trace_macros
源文件 alloc/src/macros.rs
vec formatRust自帶的聲明宏:
常用的宏函數(shù):assert, cfg, dbg, env, format, eprintln, println, panic, vec。
-------------------------------------------------------------------------------宏導入導出用 #[macro_use] 和 #[macro_export]。父模塊中定義的宏對其下的子模塊是可見的,要想子模塊中定義的宏在其后面的父模塊中可用,需要使用 #[macro_use]。*/use std::collections::HashMap;//-----------------------通用元編程的聲明式宏 macro_rules!-------------------------//一個空的宏
macro_rules! hey{() => {}
}//可以定義多條宏規(guī)則 感覺就像函數(shù)重載
macro_rules! hey2{() => {};() => {}
}//其中name可以更改名字 expr不可更改
macro_rules! yo{($name:expr) => {println!("Yo {}!",$name);}
}//函數(shù)可以打印自己的名字
macro_rules! create_function {($func_name:ident) => (fn $func_name() {println!("function {:?} is called", stringify!($func_name))})
}//多參數(shù)的宏
macro_rules! hey3{($($name:expr),*) => {}
}//輸入源是成對出現(xiàn)的 =>寫法是宏規(guī)則定的,不可更改
macro_rules! hey4{($($key:expr => $value:expr), *) => {{let mut map = HashMap::new();$(map.insert($key, $value);) *map}}
}//看一個 vec! 稍微簡化的定義
//注意:標準庫中實際定義的 vec! 包括預分配適當量的內存。這部分為代碼優(yōu)化,為了讓示例簡化,此處并沒有包含在內。
#[macro_export]
macro_rules! vec {( $( $x:expr ),* ) => {{let mut temp_vec = Vec::new();$(temp_vec.push($x);)*temp_vec}};
}//-----------------------自定義 derive 的過程式宏-------------------------
extern crate hello_macro;
#[macro_use]
extern crate hello_macro_derive;use hello_macro::HelloMacro;#[derive(HelloMacro)]
struct Pancakes;/*
hello_macro_derive存在的意義:其實我們完全不用hello_macro_derive也可以實現(xiàn)類似功能
然而,他們需要為每一個他們想使用 hello_macro 的類型編寫實現(xiàn)的代碼塊。我們希望為其節(jié)約這些工作。
另外,我們也無法為 hello_macro 函數(shù)提供一個能夠打印實現(xiàn)了該 trait 的類型的名字的默認實現(xiàn):Rust 沒有反射的能力,因此其無法在運行時獲取類型名。我們需要一個在運行時生成代碼的宏。extern crate hello_macro;
use hello_macro::HelloMacro;
struct Pancakes;
impl HelloMacro for Pancakes {fn hello_macro() {println!("Hello, Macro! My name is Pancakes!");}
}
*/
fn main() {//-----------------------通用元編程的聲明式宏 macro_rules!-------------------------hey!();yo!("666666666666");yo!["666666666666"];yo!{"666666666666"};//yo!<"666666666666">; 前三種寫法都是正確的,唯獨這個不行create_function!(foo);foo();hey3! ("Finn", "Jake", "PB");let user = hey4! ("liujiayu" => 30,"liuyalin" => 31);println!("user {:?}",user);//-----------------------自定義 derive 的過程式宏-------------------------Pancakes::hello_macro();
}/*
-----------------------自定義 derive 的過程式宏依賴-------------------------
本包toml:
[dependencies]
hello_macro = { path = "./hello_macro" }
hello_macro_derive = { path = "./hello_macro/hello_macro_derive" }
------------------------------------------------------------------------------------
hello_macro包lib.rs:
/*
對于一個 foo 的包來說,一個自定義的派生過程式宏的包被稱為 foo_derive
*/
pub trait HelloMacro {fn hello_macro();
}
----------------------------------------------------------------------------------
hello_macro_derive包lib.rs:
extern crate proc_macro;
extern crate syn;
#[macro_use]
extern crate quote;use proc_macro::TokenStream;#[proc_macro_derive(HelloMacro)]
pub fn hello_macro_derive(input: TokenStream) -> TokenStream {// Construct a string representation of the type definitionlet s = input.to_string();// Parse the string representationlet ast = syn::parse_derive_input(&s).unwrap();// Build the impllet gen = impl_hello_macro(&ast);// Return the generated implgen.parse().unwrap()
}fn impl_hello_macro(ast: &syn::DeriveInput) -> quote::Tokens {let name = &ast.ident;quote! {impl HelloMacro for #name {fn hello_macro() {println!("impl_hello_macro--->Hello, Macro! My name is {}", stringify!(#name));}}}
}
----------------------------------------------------------------------------------
hello_macro_derive包toml:
[lib]
proc-macro = true[dependencies]
syn = "0.11.11"
quote = "0.3.15"*/
?
總結
以上是生活随笔為你收集整理的34.rust宏.txt的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 33.文件与 IO.rs
- 下一篇: 36.rustc编译参数.txt