【问题标题】:Unexpected Token in Rust MacroRust 宏中的意外标记
【发布时间】:2015-09-07 14:25:12
【问题描述】:

我正在尝试为我正在编写的一些自定义结构编写一个扩展为 impls 集合的宏。这就是我所拥有的:

pub trait ComponentWise : Clone + Copy {
  fn new(x: f32, y: f32, z: f32) -> Self;
  
  fn x(&self) -> f32;
  fn y(&self) -> f32;
  fn z(&self) -> f32;

  fn has_nans(&self) -> bool {
    f32::is_nan(self.x()) || 
    f32::is_nan(self.y()) || 
    f32::is_nan(self.z())
  }
}

macro_rules! component_wise_impls { 
  ($T:ty) => {
    impl ComponentWise for $T {
      fn new(x: f32, y: f32, z: f32) -> $T {
        let x: $T = $T { vals: [x, y, z] };
        debug_assert!(!x.has_nans());
        x
      }
   };
}

pub struct Vector {
  pub vals: [f32; 3]
}

component_wise_impls!(Vector);

很遗憾,有人告诉我:

错误:意外标记:向量

让 x: $T = $T { vals: [x, y, z] };

我有点惊讶,因为我可以做到 Vector { vals: [x, y, z] },而且我认为这正是 $T { vals: [x, y, z] }; 扩展的内容。有没有办法在宏中编写这个new 函数?

【问题讨论】:

    标签: rust


    【解决方案1】:

    这是有效的:

    macro_rules! component_wise_impls {
        ($T:ident) => {
            impl ComponentWise for $T {
                fn new(x: f32, y: f32, z: f32) -> $T {
                    let x: $T = $T { vals: [x, y, z] };
                    debug_assert!(!x.has_nans());
                    x
                }
            }
        }
    }
    

    您不能在需要表达式的地方使用ty

    来自page

    插值$argument_name 可以出现在与其片段说明符一致的任何位置(即,如果它被指定为ident,它可以在任何允许标识符的地方使用)。

    正如lllogiq指出的,你必须实现xyz方法,所以完整的代码是:

    pub trait ComponentWise : Clone + Copy {
      fn new(x: f32, y: f32, z: f32) -> Self;
    
      fn x(&self) -> f32;
      fn y(&self) -> f32;
      fn z(&self) -> f32;
    
      fn has_nans(&self) -> bool {
        f32::is_nan(self.x()) || 
        f32::is_nan(self.y()) || 
        f32::is_nan(self.z())
      }
    }
    
    macro_rules! component_wise_impls {
        ($T:ident) => {
            impl ComponentWise for $T {
                fn new(x: f32, y: f32, z: f32) -> $T {
                    let x: $T = $T { vals: [x, y, z] };
                    debug_assert!(!x.has_nans());
                    x
                }
    
                fn x(&self) -> f32 {
                    self.vals[0]
                }
    
                fn y(&self) -> f32 {
                    self.vals[1]
                }
    
                fn z(&self) -> f32 {
                    self.vals[2]
                }
            }
        }
    }
    
    #[derive(Copy, Clone)]
    pub struct Vector {
      pub vals: [f32; 3]
    }
    
    component_wise_impls!(Vector);
    

    【讨论】:

    • @anjruu:您还必须实现x/y/z() 函数并让Vector 实现CopyClone 才能工作。
    猜你喜欢
    • 2023-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-27
    • 1970-01-01
    • 2020-09-28
    • 2018-08-02
    • 2020-10-03
    相关资源
    最近更新 更多