繁体   English   中英

Rust宏中的意外令牌

[英]Unexpected Token in Rust Macro

我正在尝试编写一个宏,扩展为我正在编写的一些自定义结构的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函数?

这是有效的:

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

从这个页面

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

正如llogiq指出的那样,你必须实现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);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM