Есть ли способ избежать клонирования при преобразовании PathBuf
в String
?
Абсолютно. Однако это не то, что вы делаете. Вы принимаете частьPathBuf
через file_name
и конвертируете это. Вы не можете взять на себя ответственность за часть строки.
Если вы не принимали подмножество, то преобразование всего PathBuf
может быть выполнено путем преобразования в OsString
, а затем в String
. Здесь, я игнорировать определенные ошибки и просто возвращают успех или неудача:
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())
}
Есть ли способ избежать этого &OsStr -> &str -> String -> &str
цикла?
Нет, потому что вы создаете String
(или OsString
или PathBuf
, в зависимости от того имеет место право собственности в зависимости от варианта кода) внутри вашего метода. Проверьте Return local String as a slice (&str) за то, почему вы не можете вернуть ссылку на элемент, выделенный стекю (включая строку).
Как указано в том, что Q & А, если вы хотите иметь ссылки, дело владеющие данными должен пережить ссылки:
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"),
}
}
Ваш исходный код может быть написан не врезаться на ошибки достаточно легко
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)
}
Уход. Я думал, что не будет никакого способа, не перемещая владения за пределы функции. Просто мои сильные стороны. – mgoszcz2
@ mgoszcz2 Я не уверен, что следую за вами - в первом и третьем примерах выделяются новые данные, а во втором примере свойство * * находится вне функции. – Shepmaster
Нет, я просто вернул указатель на 'argv [0] + offset' – mgoszcz2