如何优雅地给Rust的Path追加后缀生成新PathBuf?
在Rust中优雅地为Path追加后缀生成PathBuf的方法
要给Rust里的Path追加.bak这类后缀(比如将foo.c转为foo.c.bak),直接用with_extension()会替换原有扩展名得到foo.bak,显然不符合需求。下面是几种可行的实现方式:
1. 自定义工具函数(最直观易读)
这是最清晰的方案,封装成工具函数后方便复用:
use std::path::{Path, PathBuf}; fn append_to_path(p: &Path, suffix: &str) -> PathBuf { let mut os_str = p.as_os_str().to_owned(); os_str.push(suffix); os_str.into() } // 使用示例 let p = Path::new("foo.c"); let p_bak = append_to_path(p, ".bak"); assert_eq!(p_bak, Path::new("foo.c.bak"));
2. 单表达式写法(简洁但可读性稍弱)
如果想要单表达式实现,可以借助tap crate的tap_mut方法:
- Rust 1.70及以上版本(
PathBuf::as_mut_os_string()稳定):
use std::path::Path; use tap::TapMut; let p = Path::new("foo.c"); let p_bak = p.to_owned().tap_mut(|pb| pb.as_mut_os_string().push(".bak")); assert_eq!(p_bak, Path::new("foo.c.bak"));
- Rust 1.70之前版本:
use std::path::{Path, PathBuf}; use tap::TapMut; let p = Path::new("foo.c"); let p_bak: PathBuf = p.as_os_str().to_owned().tap_mut(|os| os.push(".bak")).into(); assert_eq!(p_bak, Path::new("foo.c.bak"));
如果不想依赖第三方crate,也可以用闭包模拟类似逻辑,但可读性并不会比自定义函数更好,因此更推荐第一种方案。
内容的提问来源于stack exchange,提问作者user4815162342
相关产品推荐
相关产品推荐

