Syntax Some()在变量赋值的左边做什么?

Syntax Some()在变量赋值的左边做什么?,syntax,rust,pattern-matching,Syntax,Rust,Pattern Matching,我在读一些防锈代码,我遇到了这条线 if let Some(path) = env::args().nth(1) { 此函数的内部 fn main() { if let Some(path) = env::args().nth(1) { // Try reading the file provided by the path. let mut file = File::open(path).expect("Failed reading file.");

我在读一些防锈代码,我遇到了这条线

if let Some(path) = env::args().nth(1) {
此函数的内部

fn main() {
    if let Some(path) = env::args().nth(1) {
        // Try reading the file provided by the path.
        let mut file = File::open(path).expect("Failed reading file.");
        let mut content = String::new();
        file.read_to_string(&mut content);

        perform_conversion(content.as_str()).expect("Conversion failed.");
    } else {
        println!(
            "provide a path to a .cue file to be converted into a MusicBrainz compatible tracklist."
        )
    }
}
这行代码似乎将
env
参数分配给变量路径,但我无法确定它周围的
Some()
在做什么

我查看了的文档,了解了它在
=
的右侧使用时的工作原理,但在左侧我有点困惑

我认为这一行相当于

if let path = Some(env::args().nth(1)) {
从:

if-let表达式在语义上类似于if表达式,但 它希望后面跟着关键字let,而不是条件表达式 通过一个可反驳的模式,一个=和一个表达式。如果 =右侧的表达式与模式匹配 将执行相应的块,否则流将继续到 如果存在else块,请执行以下操作。比如if表达式,if let 表达式具有由计算的块确定的值

在这里,重要的部分是可反驳性。这里的可反驳模式可以是不同的形式。例如:

enum Test {
    First(String, i32, usize),
    Second(i32, usize),
    Third(i32),
}
您可以检查x的值以获得3种不同图案的值,如:

fn main() {
    let x = Test::Second(14, 55);
    if let Test::First(a, b, c) = x {}
    if let Test::Second(a, b) = x {} //This block will be executed
    if let Test::Third(a) = x {}
}
这称为可反驳性。但是请考虑这样的代码:

enum Test {
    Second(i32, usize),
}

fn main() {
    let x = Test::Second(14, 55);
    if let Test::Second(a, b) = x {}
}
这段代码不会编译,因为x的模式很明显,它只有一个模式。 您可以从中获得更多信息

你的想法也不正确:

if let path = Some(env::args().nth(1)) {
编译器将抛出错误,如if let pattern,因为正如引用所说:“关键字let后跟一个可反驳的模式”。在这里,“let”之后没有可反驳的模式。实际上,这段代码试图创建一个名为path的变量,该变量是一个选项,这没有意义,因为不需要“If

相反,Rust希望您这样写:

let path = Some(env::args().nth(1)); // This will be seem like Some(Some(value))
从:

if-let表达式在语义上类似于if表达式,但 它希望后面跟着关键字let,而不是条件表达式 通过一个可反驳的模式,一个=和一个表达式。如果 =右侧的表达式与模式匹配 将执行相应的块,否则流将继续到 如果存在else块,请执行以下操作。比如if表达式,if let 表达式具有由计算的块确定的值

在这里,重要的部分是可反驳性。这里的可反驳模式可以是不同的形式。例如:

enum Test {
    First(String, i32, usize),
    Second(i32, usize),
    Third(i32),
}
您可以检查x的值以获得3种不同图案的值,如:

fn main() {
    let x = Test::Second(14, 55);
    if let Test::First(a, b, c) = x {}
    if let Test::Second(a, b) = x {} //This block will be executed
    if let Test::Third(a) = x {}
}
这称为可反驳性。但是请考虑这样的代码:

enum Test {
    Second(i32, usize),
}

fn main() {
    let x = Test::Second(14, 55);
    if let Test::Second(a, b) = x {}
}
这段代码不会编译,因为x的模式很明显,它只有一个模式。 您可以从中获得更多信息

你的想法也不正确:

if let path = Some(env::args().nth(1)) {
编译器将抛出错误,如if let pattern,因为正如引用所说:“关键字let后跟一个可反驳的模式”。在这里,“let”之后没有可反驳的模式。实际上,这段代码试图创建一个名为path的变量,该变量是一个选项,这没有意义,因为不需要“If

相反,Rust希望您这样写:

let path = Some(env::args().nth(1)); // This will be seem like Some(Some(value))

其他答案涉及很多细节,可能比你需要知道的更多

基本上,这是:

if let Some(path) = env::args().nth(1) {
    // Do something with path
} else {
    // otherwise do something else
}
与此相同:


其他答案涉及很多细节,可能比你需要知道的更多

基本上,这是:

if let Some(path) = env::args().nth(1) {
    // Do something with path
} else {
    // otherwise do something else
}
与此相同: