有时候,例如在阅读一些配置文件时,您读取用户输入的文件路径,而不需要通过shell(例如,您得到~/test
)。
由于下面的Option 2
不会写入用户主目录中的测试文件,我想知道是否有比Option 1
更惯用的东西。
use std::env::var;
use std::fs::File;
use std::io::prelude::*;
use std::path::Path;
fn write_to(path: &Path) {
let mut f = File::create(path).unwrap();
f.write_all("Hi".as_bytes()).unwrap();
}
fn main() {
// Option 1
let from_env = format!("{}/test", var("HOME").unwrap());
let with_var = Path::new(&from_env);
// Create $HOME/test
write_to(with_var);
// Option 2
let with_tilde = Path::new("~/test");
// Create the test file in current directory, provided a directory ./~ exists
write_to(with_tilde);
}
字符串
- 注 :这里使用
unwrap()
来保持示例的简短。在生产代码中应该有一些错误处理。
2条答案
按热度按时间332nm8kg1#
1.最惯用的方法是只使用现有的crate,在这种情况下,
shellexpand
(github,crates.io)似乎可以做你想要的:字符串
dirs
(crates.io)。下面是一个草图:型
使用示例:
型
一些评论:
P: AsRef<Path>
输入类型模仿标准库的功能。这就是为什么该方法接受所有类似Path
的输入,如&str
、&OsStr
和&Path
。Path::new
不分配任何东西,它指向与&str
完全相同的字节。strip_prefix("~/").unwrap()
在这里应该永远不会失败,因为我们检查了路径以~
开始,而不仅仅是~
。唯一的方法是路径从~/
开始(因为starts_with
是如何定义的)。vm0i2vca2#
编辑:
expanduser
crate可能可以实现您想要的一切 ,包括~user
的扩展。示例(改编自文档):字符串
原始答案:
下面是一个返回
Cow<Path>
的实现,这样我们只在路径中实际存在波浪号前缀时才分配:型
注意事项:
unwrap
是lazy_static!
块中的那个,但无法从中恢复。join
中。一些用法示例:
型