在1.88之前,我们写多层if let或者while let 会导致代码层级过多的问题,下面是个例子:

struct Foo1 {
    foo: Option<String>,
}

struct Foo2 {
    foo1: Option<Foo1>,
}

struct Foo3 {
    foo2: Option<Foo2>,
}

fn main() {
    let foo3 = Foo3 {
        foo2: Some(Foo2 {
            foo1: Some(Foo1 {
                foo: Some("foo".to_string()),
            }),
        }),
    };
    // 这里要一层一层的if let下去,可读性很差也很不优雅
    if let Some(foo2) = foo3.foo2 {
        if let Some(foo1) = foo2.foo1 {
            if let Some(foo) = foo1.foo {
                if foo == "foo" {
                    println!("I got foo!");
                }
            }
        }
    }
}

在1.88之后(注意Cargo.toml里的edition需要是2024),可以这么写:

struct Foo1 {
    foo: Option<String>,
}

struct Foo2 {
    foo1: Option<Foo1>,
}

struct Foo3 {
    foo2: Option<Foo2>,
}

fn main() {
    let foo3 = Foo3 {
        foo2: Some(Foo2 {
            foo1: Some(Foo1 {
                foo: Some("foo".to_string()),
            }),
        }),
    };
    
    // 使用let链,直接一个if解决深度嵌套问题
    if let Some(foo2) = foo3.foo2
        && let Some(foo1) = foo2.foo1
        && let Some(foo) = foo1.foo
        && foo == "foo"
    {
        println!("I got foo: {foo}")
    }
}

现在的这种扁平化写法可以让条件判断一目了然,且变量会在同一个作用域里声明,解决了多层嵌套导致的代码横向膨胀问题。