【发布时间】:2022-09-24 08:08:06
【问题描述】:
我试图在循环中爬上一条路径,直到满足路径上的某个条件。似乎一种有效的方法是使用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() 的path 和let Some(path) 的path 名称相同,但它们是按范围分隔的?你能详细说明我的误解吗?有没有更惯用的方法来做这种事情?
-
是的,
Some(path)中的path遮蔽了外部path。 -
顺便说一句,我可能会做类似
path.ancestors().any(path_matches_condition)的事情,而不是你的 while 循环。 -
@PitaJ,很好的建议。在我的实际用例中,我需要第一个匹配条件的祖先,所以我认为
path.ancestors方法不会顺利工作。我不确定ancestors的顺序是否得到保证,是否有一个好方法可以在第一次匹配后打破迭代。如果您有建议,我欢迎另一个答案。 -
在这种情况下,
path.ancestors().find(path_matches_condition)将返回符合条件的第一个祖先。从该方法的文档来看,它似乎很清楚它从path开始并向后迭代:path.parent()、path.parent().parent()等