【问题标题】:Read from an enum without pattern matching从没有模式匹配的枚举中读取
【发布时间】:2018-01-10 10:27:33
【问题描述】:

Rust documentation gives this example,我们有一个名为 some_valueResult<T, E> 实例:

match some_value {
    Ok(value) => println!("got a value: {}", value),
    Err(_) => println!("an error occurred"),
}

有什么方法可以在没有模式匹配的情况下从some_value 读取?在运行时甚至不检查内容的类型怎么办?也许我们以某种方式绝对确定地知道包含什么类型,或者我们只是一个糟糕的程序员。无论哪种情况,我只是想知道这是否可能,而不是是否是个好主意。

我觉得这是一个非常有趣的语言特性,这个分支很难(或不可能?)避免。

【问题讨论】:

标签: enums rust discriminated-union


【解决方案1】:

在最低级别,不,如果没有match1,您将无法读取枚举字段。

枚举上的方法可以更方便地访问枚举中的数据(例如Result::unwrap),但在底层,它们总是使用match 实现。

如果您知道 match 中的特定案例无法访问,通常的做法是在该分支上写入 unreachable!()unreachable!() 只需扩展为带有特定消息的 panic!())。


1 如果您有一个只有一个变体的枚举,您还可以编写一个简单的let 语句来解构该枚举。 letmatch 语句中的模式必须是详尽的,并且与枚举中的单个变体匹配的模式是详尽的。但是只有一个变体的枚举几乎从未使用过。一个结构可以很好地完成这项工作。如果您打算稍后添加变体,最好立即写match

enum Single {
    S(i32),
}

fn main() {
    let a = Single::S(1);
    let Single::S(b) = a;
    println!("{}", b);
}

另一方面,如果您有一个包含多个变体的枚举,如果您只对来自单个变体的数据感兴趣,也可以使用if letwhile letletmatch 需要详尽的模式,if letwhile let 接受非详尽的模式。你会经常看到它们与Option一起使用:

fn main() {
    if let Some(x) = std::env::args().len().checked_add(1) {
        println!("{}", x);
    } else {
        println!("too many args :(");
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-10
    • 2014-10-23
    • 1970-01-01
    • 2013-07-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多