我试图用循环爬取路径,直到路径上满足某个条件为止。似乎使用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;
}
}
然而,这会导致无限循环,因为在循环语句中未重新分配
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()
的路径和 let Some(path)
的路径虽然名称相同,但它们被不同的作用域隔离开了。您是否能详细说明我的误解?有没有更常用的方法来完成这种操作?
Some(path)
中的path
遮蔽了外部的path
。 - PitaJpath.ancestors().any(path_matches_condition)
,而不是使用你的 while 循环。 - PitaJpath.ancestors
方法会很顺利地工作。我不确定ancestors
的顺序是否得到保证,以及是否有一种好的方法在第一次匹配后跳出迭代。如果您有建议,我欢迎另一个答案。 - bicarlsenpath.ancestors().find(path_matches_condition)
将返回符合条件的第一个祖先。从该方法的文档中可以看出,它从path
开始向后迭代:path.parent()
、path.parent().parent()
等。 - PitaJ