从没有模式匹配的枚举中读取

时间:2017-08-03 02:07:04

标签: enums rust discriminated-union

Rust documentation gives this example我们的Result<T, E>实例名为some_value

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

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

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

1 个答案:

答案 0 :(得分:10)

在最低级别,不,你不能在没有match 1 的情况下阅读枚举字段。

枚举上的方法可以更方便地访问枚举中的数据(例如Result::unwrap),但在引擎盖下,它们始终使用match实现。

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

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

enum Single {
    S(i32),
}

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

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

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