我遇到了一个问题,就是在闭包中的 Option
内部仍然被借用时,一个值被丢弃了,但我很难完全理解发生了什么。为了说明这一点,以下是一个实际尝试实现的工作示例:
fn foo() -> Option<String> {
let hd = match std::env::home_dir() {
Some(d) => d,
None => return None,
};
let fi = match hd.file_name() {
Some(f) => f,
None => return None,
};
let st = match fi.to_str() {
Some(s) => s,
None => return None,
};
Some(String::from(st))
}
返回值是当前用户的主目录名称,包含在 Option<String>
中。
我想尝试使用组合器对此进行重构,以消除行 None => return None,
。
std::env::home_dir()
.and_then(|d| d.file_name())
.and_then(|f| f.to_str())
.map(String::from)
但是rustc检测到一个引用超出了它的值。
error: `d` does not live long enough
--> src/main.rs:33:35
|
33 | .and_then(|d| d.file_name())
| - ^ `d` dropped here while still borrowed
| |
| borrow occurs here
34 | .and_then(|f| f.to_str())
35 | .map(String::from)
| - borrowed value needs to live until here
我认为这是因为 Option<&OsStr>
中的引用超出了类型 PathBuf
的值的生命周期。然而,我仍然很难想象在没有值过早超出范围的情况下如何解决这个问题。
为了进一步说明我的目标,这里有一个实现了 Copy trait 的类型的类似示例。
let x = 42u16.checked_add(1234)
.and_then(|i| i.checked_add(5678))
.and_then(|i| i.checked_sub(90))
.map(|i| i.to_string());
println!("{:?}", x); // Some("6864")
在前面的例子中,我肯定忽略了一些与所有权相关的内容。使用 Option<PathBuf>
是可能的吗?