目前在rust的宏里直接访问结构体的成员是不可行的,但是可以通过变通的方法来做
例如下面的代码就是不可行的,$m.id
或者$m.code
会提示出错
macro_rules! msg {
($id:expr,$code:expr,$f:ident,$m:ident)=>{
if $id == $m.id && $code == $m.code {
...
}
}
}
因为宏里可以访问全局函数,所以可以曲线来访问结构体成员
这些全局函数加上了inline
,理论上这个曲线方法和直接访问结构体成员的性能是一样的
#[derive(Debug)]
struct Event{
hwnd: usize,
msg: u32,
r: u32,
wparam: usize,
lparam: usize,
}
impl Event{
#[inline(always)]
fn get_id(&self)->u16 {
(self.wparam & 0xFFFF) as u16
}
#[inline(always)]
fn get_code(&self)->u16{
((self.wparam >> 16) & 0xFFFF) as u16
}
#[inline(always)]
fn set_result(&mut self,r:u32){
self.r=r;
}
}
macro_rules! msg {
($id:expr,$code:expr,$f:ident,$e:ident)=>{
if $id == Event::get_id($e) && $code == Event::get_code($e) {
$f($e);
}
}
}
fn bar(e: &mut Event){
e.set_result(300);
println!("{:?}",e);
}
fn foo(e: &mut Event){
msg!(100,200,bar,e);
}
fn main(){
let mut e = Event{hwnd:0,msg:0,r:0,wparam:0xc80064,lparam:0};
foo(&mut e);
}
play网址:https://play.rust-lang.org/?gist=454b5441c1db5dc6a1e1&version=stable
运行结果:Event { hwnd: 0, msg: 0, r: 300, wparam: 13107300, lparam: 0 }