在if语句中使用Rust生存期

6za6bjd0  于 2022-11-12  发布在  其他
关注(0)|答案(2)|浏览(143)

我在for循环中有一个if语句,我希望它创建一个变量,该变量的生命周期为for循环的迭代周期。

for condition_raw in conditions_arr {
        println!("{}", condition_raw);
        let matching = !condition_raw.contains('!');
        if matching {
            let index = condition_raw.find('=').unwrap_or_default();
        } else {
            let index = condition_raw.find('!').unwrap_or_default();
        }
        let key = &condition_raw[..index];
    }

let key = &condition_raw[..index];当前引发在此范围内找不到值index在此范围内找不到rustc E0425

wd2eg0qa

wd2eg0qa1#

  • 我将忽略condition变量,该变量在您的示例中似乎根本没有使用。*

let语句创建的绑定最多只能在当前作用域中保存。因此,当您在if * 内部 * 创建index变量时,您无法在其他任何地方访问它。有两种方法可以解决此问题。
第一种方法是将index显式声明为外部作用域的一部分,并且只在if语句中定义它。

for condition_raw in conditions_arr {
    let matching = !condition_raw.contains('!');
    let index;
    if matching {
        index = condition_raw.find('=').unwrap_or_default();
    } else {
        index = condition_raw.find('!').unwrap_or_default();
    }
    let key = &condition_arr[..index];
}

由于Rust将确保index已定义,因此不存在意外未定义index的风险(恰好一次)。然而,这并不是一个好的解决方案,因为它违反了“局部性”原则,即代码片段应该对代码片段有影响,或者代码片段应该“足够接近”。在这种情况下,let index;与它的定义并不太远,但它可以任意远,这使得阅读您代码的人很难记住有一个已声明但尚未定义的。
或者,您可以使用Rust中的大多数内容都是表达式这一事实:

for condition_raw in conditions_arr {
    let matching = !condition_raw.contains('!');
    let index = if matching {
        condition_raw.find('=').unwrap_or_default();
    } else {
        condition_raw.find('!').unwrap_or_default();
    }
    let key = &condition_arr[..index];
}

但是,实际上,您可以对代码进行更多的因子分解,这通常会更好:

for condition_raw in conditions_arr {
    let matching = !condition_raw.contains('!');
    let index = condition_raw.find(if matching {
        '='
    } else {
        '!'
    }).unwrap_or_default();
    let key = &condition_arr[..index];

或者,甚至更多

for condition_raw in conditions_arr {
    let index = condition_raw
        .find('!')
        .or_else(|| condition_raw.find('='))
        .unwrap_or_default();
    let key = &condition_arr[..index];
}
zzwlnbp8

zzwlnbp82#

从if else陈述式指派变数的惯用方式如下:

let index: usize = if matching {
            condition_raw.find('=').unwrap_or_default()
        } else {
            condition_raw.find('!').unwrap_or_default()
        };

Idiomatic way of assigning a value from an if else condition in Rust
在Rust中,if/else块是一个表达式。也就是说,块本身有一个值,等价于执行的任何部分中的最后一个表达式。考虑到这一点,我将这样构造代码:

相关问题