【问题标题】:How to create a macro that gets the value of an enum type?如何创建一个获取枚举类型值的宏?
【发布时间】:2017-05-10 05:05:15
【问题描述】:

我的枚举如下所示:

#[derive(Clone, Debug)]
pub enum Type {
    GLnull,
    GLenum(GLenum),
    GLboolean(GLboolean),
    GLint(GLint),
    GLbyte(GLbyte),
    GLshort(GLshort),
    GLclampx(GLclampx),
    GLubyte(GLubyte),
    GLushort(GLushort),
    GLuint(GLuint),
    GLsizei(GLsizei),
    GLclampf(GLclampf),
    GLdouble(GLdouble),
    GLclampd(GLclampd),
    GLfloat_4fv((GLfloat, GLfloat, GLfloat, GLfloat)),
    GLfloat(GLfloat),
    GLintptr(GLintptr),
    GLsizeiptr(GLsizeiptr),
    GLbitfield(GLbitfield),
    GLchar_ptr(String),
}

macro_rules! get{
    ($e:expr) => {
        match $e {
            Type::GLsizei(x) => { x }
            Type::GLbitfield(x) => { x }
            _ => { 0 }
        }
    }
}

现在如何创建一个获取枚举类型值的宏?

【问题讨论】:

  • 您希望它如何工作?根据匹配的模式,您不能编写具有不兼容类型的匹配项。那只是没有类型检查。另一种方法是使用一个宏来尝试提取给定变量的值,但你也可以选择一个函数(或者只使用if let)。

标签: enums macros rust


【解决方案1】:

就像@aochagavia 所说,如果你必须对你的枚举做特定的事情,那么有一个宏是没有意义的。

下面的宏可以帮助你,目的是有一个宏来创建一个枚举并生成一些方法。这仅在所有变体都具有一种类型时才有效。

macro_rules! foo {
    ($($(#[$meta:meta])* foo $name:ident($ty:ty),)*) => {
        #[derive(Debug, Clone)]
        pub enum Foo {
            $($(#[$meta])* $name($ty),)*
        }
        impl Foo {
            pub fn display(&self) {
                match *self {
                    $(Foo::$name(x) => println!("{}", x),)*
                }
            }
        }
    }
}

foo! {
    foo A(i32),
    foo B(i64),
}

fn main() {
    let a = Foo::A(32);
    let b = Foo::B(64);

    a.display();
    b.display();
}

original 宏来自@koka-el-kiwi,我以它为例并针对您的情况进行修改。

【讨论】:

  • @Shepmaster 只是一个问题,是你否决了我?如果是这样,你能告诉我为什么吗?这不回答问题? “如何创建一个获取枚举类型值的宏?”
【解决方案2】:

以下方法也可以

pub enum Type<T> {
    gli32(T),
    gli64(T),
    glfloat4fv(T),
    glString(T),
    glVec(T),
}

impl<T> Type<T> {
    pub fn unwarp(&self) -> &T {
        match *self {
            Type::gli32(ref x) => x,
            Type::gli64(ref x) => x,
            Type::glfloat4fv(ref x) => x,
            Type::glString(ref x) => x,
            Type::glVec(ref x) => x,
        }
    }
}

fn main() {
    println!("Hello, world!");
    let f = Type::gli32(32 as i32);
    let ff64 = Type::gli64((64, 32));
    let f4fv = Type::glfloat4fv((0.1, 0.2, 0.0));
    let cstr = Type::glString(CString::new("glstring").unwrap());
    let ve = [1, 2, 3, 5];
    let glve = Type::glVec(ve);

    println!("f ={} {:?} {:?} {:?}",
             f.unwarp(),
             f4fv.unwarp(),
             cstr.unwarp(),
             glve.unwarp());
}

【讨论】:

  • 巨大的代码块应该伴随着散文来描述做了什么更改以及为什么它们解决了问题。
  • 另外,拼写为unwrap
  • 这没有按预期工作,它创建了 5 个枚举。没有。
猜你喜欢
  • 1970-01-01
  • 2023-01-14
  • 2015-02-10
  • 2011-11-07
  • 2017-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多