我试图在一条小路上循环爬行,直到满足小路上的某个条件.要做到这一点似乎是一种有效的方法,那就是在每个循环中使用while let循环将循环变量重新赋值为parent.

let path = std::path::Path::new("/my/long/path/to/a/file.txt");
while let Some(path) = path.parent() {
    println!("{:?}", path);
    
    if path_matches_condition(&path) {
        println!("{:?} path matched", path);
        break;
    }
}

但是,这会导致无限循环,因为在LOOP语句中没有重新分配path.

我本以为while let Some(path) = path.parent()语句每次都会重新分配path,但这并没有发生,path.parent()path也没有改变. 即上述程序的输出将被重复"/my/long/path/to/a",直到该程序被手动终止.

这可以通过分离两个变量并在循环内手动重新赋值来解决.

let mut path = std::path::Path::new("/my/long/path/to/a/file.txt");
while let Some(parent) = path.parent() {
    println!("{:?}", path);
    
    if path_matches_condition(&path) {
        println!("{:?} path matched", path);
        break;
    }

    path = parent;
}

这是因为,尽管path.parent()pathlet Some(path)path同名,但它们的作用域是分开的吗?你能详细解释一下我的误解吗?有没有更惯用的方式来做这类事情呢?

推荐答案

你所做的和你所拥有的the documentation之间的显著区别是,你确实从来没有重新分配过path--但我认为你误解了哪里没有重新分配.

这份声明:

let path = ...
while let Some(p) = path.parent() { ... }

path,然后打parent().Some(p)中的ppath不是同一个变量.在您的代码中,当您放置Some(path)时,您正在跟踪外部作用域为path的变量.但是,一旦第一个循环结束,这个阴影就消失了,并且您实际上没有重新赋值path,因此path.parent()返回与以前相同的值.

因此,您可能需要以下内容:

let path = (...)
let parent_path = path.parent()
while let Some(p) = parent_path { 
    ... 
    parent_path = p.parent();
}

注意,之所以会出现阴影,是因为let Some(p) = path.parent()正在进行解构.与Match语句非常相似-请考虑以下代码:

fn main() {
    let path: Option<&str> = Some("A path");
    match path {
        Some(path: &str) => println!("{:#?}", path),
        None => println!("Nuthin!")
    }
    println!("{:#?}", path);
}

这段代码编译得很干净,但我们可以清楚地看到,前pathOption,而里面的是&str.输出为:

"A path"
Some(
    "A path",
)

Rust相关问答推荐

as操作符如何将enum转换为int?

在Rust中创建可变片段的可变片段的最有效方法是什么?

收集RangeInclusive T到Vec T<><>

trait声明中的生命周期参数

关于Rust 中回归的逻辑

防止cargo test 中的竞争条件

在UdpSocket上使用sendto时的隐式套接字绑定

原始数组数据类型的默认trait实现

为什么 Rust 需要可变引用的显式生命周期而不是常规引用?

从 rust 函数返回 &HashMap

如何使用 Bincode 在 Rust 中序列化 Enum,同时保留 Enum 判别式而不是索引?

Google chrome 和 Apple M1 中的计算着色器

trait 对象指针的生命周期

`tokio::pin` 如何改变变量的类型?

我如何取消转义,在 Rust 中多次转义的字符串?

在给定 Rust 谓词的情况下,将 Some 转换为 None 的惯用方法是什么?

仅当函数写为闭包时才会出现生命周期错误

如何连接 Rust 中的相邻切片

相交着色器从 SSBO 中读取零

通用类型,不同于输入类型,作为函数的返回值