如何追加到 PathBuf

use*_*342 5 path rust

有没有一种优雅的方法来附加后缀(例如.baka )Path并获得新的后缀PathBuf?就像是:

let p = Path::new("foo.c");
let p_bak = /* ? */;
assert_eq!(p_bak, Path::new("foo.c.bak"));
Run Code Online (Sandbox Code Playgroud)

有了字符串,就可以使用format!("{}.bak", p). 对于一条路径,我看不到明显的等价物。with_extension()并没有完全做到这一点,因为p.with_extension("bak")将创建foo.bak而不是所需的foo.c.bak.

最“明显”的解决方案是定义append_to_path()并使用append_to_path(p, ".bak")

fn append_to_path(p: &Path, s: &str) -> PathBuf {
    let mut p_osstr = p.as_os_str().to_owned();
    p_osstr.push(s);
    p_osstr.into()
}
Run Code Online (Sandbox Code Playgroud)

有没有更简短的表达方式?

tap板条箱允许将其放入一种简化的表达式中,但它仍然感觉相当神秘:

// prior to Rust 1.70:
let p_bak: PathBuf = p.as_os_str().to_owned().tap_mut(|s| s.push(".bak")).into();

// since Rust 1.70:
let p_bak = p.to_owned().tap_mut(|s| s.as_mut_os_string().push(".bak"));
Run Code Online (Sandbox Code Playgroud)

Ous*_*udi -2

let p_bak: PathBuf = (p.to_string_lossy().to_string() + ".bak").into();
// or
let p_bak: PathBuf = PathBuf::from(p.to_string_lossy().to_string() + ".bak");
Run Code Online (Sandbox Code Playgroud)

的用法to_string_lossy避免使用to_stringwhich 返回Option<&str>,但仅当我们知道字符串将由有效的 unicode 字符组成时才应使用