找不到类型为`std :: option :: Option <&std :: ffi :: OsStr>`的名为`to_str`的​​方法

时间:2019-02-02 00:01:55

标签: rust

这是我当前尝试遍历目录并将扩展名添加到映射并计算具有该扩展名类型的文件的数量。

由于

,对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;
        }
    }
}

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}}特性实现)