Y at-il un moyen d'éviter le clonage lors de la conversion d'un PathBuf
à un String
?
Absolument. Cependant, ce n'est pas ce que vous faites. Vous prenez une partie du PathBuf
via file_name
et convertir cela. Vous ne pouvez pas prendre possession d'une partie d'une chaîne.
Si vous ne preniez pas de sous-ensemble, la conversion d'un PathBuf
entier peut être effectuée en convertissant en OsString
puis en String
. Ici, j'ignore les erreurs spécifiques et juste retour succès ou l'échec:
use std::path::PathBuf;
fn exe_name() -> Option<String> {
std::env::current_exe()
.ok()
.map(PathBuf::into_os_string)
.and_then(|exe| exe.into_string().ok())
}
Est-il possible d'éviter ce cycle &OsStr -> &str -> String -> &str
?
Non, parce que vous créez le String
(ou OsString
ou PathBuf
, selon détient une participation en fonction de la variante de code) à l'intérieur de votre méthode. Consultez Return local String as a slice (&str) pour savoir pourquoi vous ne pouvez pas renvoyer une référence à un élément alloué par une pile (y compris une chaîne).
Comme indiqué dans ce Q & A, si vous voulez avoir des références, la chose de posséder les données doit survivre les références:
use std::env;
use std::path::Path;
use std::ffi::OsStr;
fn binary_name(path: &Path) -> Option<&str> {
path.file_name().and_then(OsStr::to_str)
}
fn main() {
let exe = env::current_exe().ok();
match exe.as_ref().and_then(|e| binary_name(e)) {
Some("cat") => println!("Called as cat"),
Some("dog") => println!("Called as dog"),
Some(other) => println!("Why did you call me {}?", other),
None => println!("Not able to figure out what I was called as"),
}
}
Votre code original peut être écrit pour ne pas tomber en panne sur erreurs assez facilement
fn binary_name() -> Option<String> {
let exe = std::env::current_exe();
exe.ok()
.as_ref()
.and_then(|p| p.file_name())
.and_then(|s| s.to_str())
.map(String::from)
}
Neat. Je pensais qu'il n'y aurait aucun moyen sans déplacer la propriété en dehors de la fonction. Juste mes manières de C qui brillent à travers. – mgoszcz2
@ mgoszcz2 Je ne suis pas sûr que je te suis - dans les premier et troisième exemples, de nouvelles données sont alloués, et dans le second exemple, la propriété * est * à l'extérieur de la fonction. Non, ce – Shepmaster
est juste en C Je voudrais juste revenir un pointeur vers 'argv [0] + offset' – mgoszcz2