从没有模式匹配的枚举中读取
Read from an enum without pattern matching
Rust documentation gives this example 我们有一个名为 some_value
:
的 Result<T, E>
实例
match some_value {
Ok(value) => println!("got a value: {}", value),
Err(_) => println!("an error occurred"),
}
有什么方法可以在不进行模式匹配的情况下从 some_value
中读取数据吗?如果在运行时甚至不检查内容的类型呢?也许我们以某种方式绝对确定包含什么类型,或者我们只是一个糟糕的程序员。无论哪种情况,我只是想知道它是否完全可行,而不是它是否是个好主意。
我觉得这是一个非常有趣的语言特性,这个分支很难(或不可能?)避免。
At the lowest level, no, you can't read enum fields without a match
1.
Methods on an enum can provide more convenient access to data within the enum (e.g. Result::unwrap
), but under the hood, they're always implemented with a match
.
If you know that a particular case in a match
is unreachable, a common practice is to write unreachable!()
on that branch (unreachable!()
simply expands to a panic!()
with a specific message).
1 If you have an enum with only one variant, you could also write a simple let
statement to deconstruct the enum. Patterns in let
and match
statements must be exhaustive, and pattern matching the single variant from an enum is exhaustive. But enums with only one variant are pretty much never used; a struct would do the job just fine. And if you intend to add variants later, you're better off writing a match
right away.
enum Single {
S(i32),
}
fn main() {
let a = Single::S(1);
let Single::S(b) = a;
println!("{}", b);
}
On the other hand, if you have an enum with more than one variant, you can also use if let
and while let
if you're interested in the data from a single variant only. While let
and match
require exhaustive patterns, if let
and while let
accept non-exhaustive patterns. You'll often see them used with Option
:
fn main() {
if let Some(x) = std::env::args().len().checked_add(1) {
println!("{}", x);
} else {
println!("too many args :(");
}
}
Rust documentation gives this example 我们有一个名为 some_value
:
Result<T, E>
实例
match some_value {
Ok(value) => println!("got a value: {}", value),
Err(_) => println!("an error occurred"),
}
有什么方法可以在不进行模式匹配的情况下从 some_value
中读取数据吗?如果在运行时甚至不检查内容的类型呢?也许我们以某种方式绝对确定包含什么类型,或者我们只是一个糟糕的程序员。无论哪种情况,我只是想知道它是否完全可行,而不是它是否是个好主意。
我觉得这是一个非常有趣的语言特性,这个分支很难(或不可能?)避免。
At the lowest level, no, you can't read enum fields without a match
1.
Methods on an enum can provide more convenient access to data within the enum (e.g. Result::unwrap
), but under the hood, they're always implemented with a match
.
If you know that a particular case in a match
is unreachable, a common practice is to write unreachable!()
on that branch (unreachable!()
simply expands to a panic!()
with a specific message).
1 If you have an enum with only one variant, you could also write a simple let
statement to deconstruct the enum. Patterns in let
and match
statements must be exhaustive, and pattern matching the single variant from an enum is exhaustive. But enums with only one variant are pretty much never used; a struct would do the job just fine. And if you intend to add variants later, you're better off writing a match
right away.
enum Single {
S(i32),
}
fn main() {
let a = Single::S(1);
let Single::S(b) = a;
println!("{}", b);
}
On the other hand, if you have an enum with more than one variant, you can also use if let
and while let
if you're interested in the data from a single variant only. While let
and match
require exhaustive patterns, if let
and while let
accept non-exhaustive patterns. You'll often see them used with Option
:
fn main() {
if let Some(x) = std::env::args().len().checked_add(1) {
println!("{}", x);
} else {
println!("too many args :(");
}
}