クロージャーで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は、その値をoutlives参照を検出します。
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
の値をoutlivingされているためこれがあると思います。しかし、私はまだ値がすぐに範囲外に出ることなくこれにアプローチする方法を考え出すのに苦労しています。
私が達成しようとしていることをさらに説明するために、コピー特性を実装するタイプの類似の例を示します。
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>
で可能ですか?