Je suis confronté à un problème avec une valeur abandonnée alors qu'elle est encore empruntée dans un Option
, dans une fermeture, mais j'ai du mal à saisir exactement ce qui est passe. Pour illustrer, voici un exemple concret de ce que je suis en train d'essayer d'atteindre:La valeur se lâche trop tôt à l'intérieur de la fermeture et le combinateur alors que l'emprunt existe
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))
}
La valeur de retour est le nom de base du répertoire de l'utilisateur courant à l'intérieur Option<String>
.
Je pensais que j'essaierais de refactoriser cela avec des combinateurs pour se débarrasser des lignes None => return None,
.
std::env::home_dir()
.and_then(|d| d.file_name())
.and_then(|f| f.to_str())
.map(String::from)
Mais rustc détecte une référence qui survit à sa valeur.
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
Je pense c'est parce que la référence en Option<&OsStr>
est la valeur de vivre plus longtemps que le type PathBuf
. Cependant, j'ai encore du mal à comprendre comment aborder cette question sans que la valeur ne soit hors de portée trop tôt.
Pour illustrer davantage ce que j'essaie d'obtenir, voici un exemple similaire avec un type qui implémente le trait Copier.
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")
Donc, je néglige définitivement quelques choses liées à la propriété dans l'exemple précédent. Est-ce possible avec Option<PathBuf>
?