这是我当前尝试遍历目录并将扩展名添加到映射并计算具有该扩展名类型的文件的数量。
由于
,对to_str()
的调用失败
no method named `to_str` found for type `std::option::Option<&std::ffi::OsStr>` in the current scope [E0599]
我尝试将其转换为其他地方的字符串,甚至尝试不评估Option
并尝试将其原样插入地图中,但这也不起作用。
extern crate walkdir;
use std::ffi::OsStr;
use std::path::Path;
use walkdir::WalkDir;
extern crate serde_json;
use serde_json::{Map, Number, Value};
fn main() {
let mut map = Map::new();
let walker = WalkDir::new("/Users/jamescampbell/").into_iter();
for entry in walker {
let entry = entry.unwrap();
let os_str = OsStr::new(entry.file_name());
let path = Path::new(os_str);
let extensioner = path.extension();
let my_new_string: String = match extensioner.to_str() {
None => String::from("crap, os_str failed"),
Some(s) => s,
};
println!("should be foo: {}", my_new_string);
if !map[s] {
map.insert(s.to_string(), Value::Number(Number::from(1u64)));
} else {
map[s] += 1;
}
}
}
答案 0 :(得分:3)
几个问题。
第一个是extension()
的结果是Option<T>
。具体而言,其为Option<&std::ffi::OsStr>
。因此,您必须将其拆开:
但这不是唯一的问题,因为在to_str()
上调用&OsStr
会返回Option<&str>
,它本身也不是String
。
在字符串类型之间进行转换时,将所有潜在的被忽略的问题都排除在外了……这是造成您问题的部分的最小重现:
use std::path::Path;
use std::ffi::OsStr;
fn main() {
let os_str = OsStr::new("example.txt");
let path = Path::new(os_str);
let extensioner = path.extension();
let my_new_string: String = extensioner.unwrap().to_str().unwrap().into();
println!("Extension: {}", my_new_string);
}
Here it is running on the playground
基本上,我们:
unwrap
Option<&OsStr>
变成&OsStr
。to_str()
上致电&OsStr
unwrap
生成的Option<&str>
变成&str
into()
,它将转换为String
(这将调用From
的{{1}}特性实现)