【问题标题】:How to match Self on associated method of enum for a given trait如何在给定特征的枚举关联方法上匹配 Self
【发布时间】:2019-11-16 14:19:36
【问题描述】:

在开始之前,我都无法适应how to match on data type in Rust 也不是 Shepmaster 的更新版本到 another question 我有。


我希望能够为枚举 BinOp 的每个变体实现 Token 特征。

#[derive(Debug, std::cmp::PartialEq)]
enum BinOp {
    Add,
    Sub
}

trait Token {
    fn regex() -> &'static str;
}

这都不行(这是我想写的)

编辑:修正错字:impl Token for BinOp 而不是 impl Token for BinOp::Add

impl Token for BinOp {
    fn regex() -> &'static str{
        match Self {
            BinOp::Add => "\\+",
            BinOp::Sub => "-"
        }
    }
}
        match Self {
              ^^^^ 
the `Self` constructor can only be used with tuple or unit structs


the `Self` constructor can only be used with tuple or unit structs

也不是

impl Token for BinOp::Add {
    fn regex() -> &'static str{
         "\\+"
    }
}
impl Token for BinOp::Add {
               ^^^^^^^^^^ not a type
expected type, found variant `BinOp::Add`

如果上面的代码能写出来,我倒是希望能这样使用

let add: BinOp = BinOp::Add;
let regex: &str = BinOp::Add::regex();

有没有比做以下更好的方法(女巫太冗长了)?

#[derive(Debug, std::cmp::PartialEq)]
struct Add;
#[derive(Debug, std::cmp::PartialEq)]
struct Sub;
#[derive(Debug, std::cmp::PartialEq)]
enum BinOp {
    Add(Add),
    Sub(Sub)
}

trait Token {
    fn regex() -> &'static str;
}

impl Token for Add {
    fn regex() -> &'static str{
         "\\+"
    }
}
impl Token for Sub {
    fn regex() -> &'static str{
         "-"
    }
}
let add: BinOp = BinOp::Add(Add);
let regex: &str = Add::regex();

不幸的是,这是 Rust 当前的限制吗?有解决办法吗?

【问题讨论】:

    标签: enums rust


    【解决方案1】:

    不幸的是,枚举变体不是 Rust 中的类型,因此您必须坚持使用“冗长”版本。

    an RFC 可以将变体作为类型,但即使它被实现,(如果我没看错的话)你也无法让它们实现特征。


    但是,在您的情况下,由于您的变体没有任何价值,您可以这样写:

    #[derive(Debug, std::cmp::PartialEq, Clone, Copy)]
    enum BinOp {
        Add,
        Sub
    }
    
    trait Token {
        fn regex(self) -> &'static str;
    }
    
    impl Token for BinOp {
        fn regex(self) -> &'static str {
            match self {
                BinOp::Add => "\\+",
                BinOp::Sub => "-",
            }
        }
    }
    
    fn main() {
        assert_eq!(BinOp::Add.regex(), "\\+");
        assert_eq!(BinOp::Sub.regex(), "-");
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-20
      • 1970-01-01
      • 2018-03-19
      相关资源
      最近更新 更多