我正在学习 Rust,我正在尝试转换一个简单的 Ruby 示例:
这是 Ruby 示例:
output_path = '~/Documents'
pattern = File.expand_path(File.join(output_path, '*', '**', '*.txt'))
Dir.glob(pattern) do |path|
puts path
end
奖金 Nim 示例:
import os
import strformat
import glob
var outputPath = expandTilde("~/Documents")
var pattern = joinPath(outputPath, "*", "**", "*.txt")
for path in walkGlob(pattern):
echo path
到目前为止,这是我对 Rust 所做的,但是,它没有构建:
use std::io;
use std::fs;
use std::path::PathBuf;
use glob::glob;
fn main() {
let output_path: io::Result<PathBuf> = fs::canonicalize("~/Documents");
let pattern: PathBuf = [output_path, "*", "**", "*.txt"].iter().collect();
for entry in glob(pattern).expect("Failed to read glob pattern") {
match entry {
Ok(path) => println!("{:?}", path.display()),
Err(e) => println!("{:?}", e),
}
}
}
我尝试了不同的变化,但没有成功。
我不确定fs::canonicalize是否真的扩展了波浪号路径。我发现了一个旧的板条箱:shellexpand::tilde。但是,我不知道如何处理它给出的输出。它不是一个str或String。
我也不确定是否需要多个级别的matchonResult和Option其中一些的返回值。最终glob想要 astr并且在我的所有变体中,第一个output_path值会搞砸,或者我不知道如何将其转换为str.
我错过了什么?这样做的惯用方法是什么?到目前为止,我尝试过的方法似乎过于冗长。有没有一种简单的方法可以做到这一点?
更新
如果我硬编码扩展路径,我最终让它工作:
use std::path::PathBuf;
use glob::glob;
fn main() {
let pattern_path_buf: PathBuf = ["", "/Users", "ejstembler", "Documents", "*", "**", "*.txt"].iter().collect();
match pattern_path_buf.to_str() {
Some(pattern) => {
println!("{:?}", pattern);
for entry in glob(pattern).expect("Failed to read glob pattern") {
match entry {
Ok(path) => println!("{:?}", path.display()),
Err(e) => println!("{:?}", e),
}
}
},
None => println!("no pattern_path_buf")
}
}
一个奇怪的细微差别是,我必须在 PathBuf "" 的开头添加一个空白字符串以使其包含前导正斜杠,否则它将丢失。我发现有std::path::MAIN_SEPARATOR,但是,我不知道如何将 a 转换char为 a &str。
无论如何,@Joe_Jingyu提供了可接受的答案shellexpand::tilde。谢谢乔!