【问题标题】:Textfile-parsing function fails to compile owing to type-mismatch error由于类型不匹配错误,文本文件解析函数无法编译
【发布时间】:2015-07-24 22:45:26
【问题描述】:

我正在尝试解析一个简单的配置文本文件,该文件每行包含一个三个单词的条目,布局如下:

ITEM name value
ITEM name value
//etc.

我已经在此处(和on the Rust Playpen)复制了执行解析(以及随后的编译错误)的函数:

pub fn parse(path: &Path) -> config_struct {

    let file = File::open(&path).unwrap();
    let reader = BufReader::new(&file);
    let line_iterator = reader.lines();
    let mut connection_map = HashMap::new();
    let mut target_map = HashMap::new();

    for line in line_iterator {

        let line_slice = line.unwrap();
        let word_vector: Vec<&str> = line_slice.split_whitespace().collect();

        if word_vector.len() != 3 { continue; }

        match word_vector[0] {
            "CONNECTION" => connection_map.insert(word_vector[1], word_vector[2]),
            "TARGET" => target_map.insert(word_vector[1], word_vector[2]),
            _ => continue,
        }
    }

    config_struct { connections: connection_map, targets: target_map }
}

pub struct config_struct<'a>  {
    // <name, value>
    connections: HashMap<&'a str, &'a str>,
    // <name, value>
    targets: HashMap<&'a str, &'a str>,
}


src/parse_conf_file.rs:23:3: 27:4 error: mismatched types:
 expected `()`,
    found `core::option::Option<&str>`
(expected (),
    found enum `core::option::Option`) [E0308]
src/parse_conf_file.rs:23 match word_vector[0] {
src/parse_conf_file.rs:24   "CONNECTION" => connection_map.insert(word_vector[1], word_vector[2]),
src/parse_conf_file.rs:25   "TARGET" => target_map.insert(word_vector[1], word_vector[2]),
src/parse_conf_file.rs:26   _ => continue,
src/parse_conf_file.rs:27 }

本质上,我似乎创建了一个match 语句,它需要一个空元组,并且还发现Vec&lt;&amp;str&gt; 的内容被包裹在Option 中!

注意。这篇文章最初包含两个问题(我认为这是一个以不同方式表现出来的错误),但根据 cmets 中的建议,我将其分成两个单独的帖子。后面的帖子是here

【问题讨论】:

  • @Shepmaster 啊,对不起。感谢您的建议 - 以及链接。似乎无法创建在 Rust Playpen 上执行的示例(它是虚拟化文件 I/O,不是吗?),但仍然设法产生两个编译错误,herehere;为了将来的读者,您认为我应该尝试将我的原件分成两个单独的帖子,还是保留它现在已经回答的状态?
  • 它是虚拟化文件 I/O,不是吗? - 我不认为它是虚拟化的,但它在沙箱中运行。例如,您可以轻松打开/etc/hosts

标签: rust text-parsing lifetime type-mismatch borrow-checker


【解决方案1】:

您最初的问题只是循环体末尾有一个非() 表达式。您的match 表达式具有Option&lt;&amp;str&gt; 类型(因为这是HashMap::insert 的返回类型),而不是() 类型。只需在匹配表达式后加一个分号即可解决此问题:

match word_vector[0] {
    "CONNECTION" => connection_map.insert(word_vector[1], word_vector[2]),
    "TARGET" => target_map.insert(word_vector[1], word_vector[2]),
    _ => continue,
};

对于后者,word_vector 不是填充了不指向 line_slice 的拥有对象吗?

不,这正是问题所在。 word_vector 包含 &amp;str 类型的元素,即借用字符串。这些指向line_slice,它只存在到当前循环迭代结束。在将它们插入地图之前,您可能希望将它们转换为 Strings(使用 String::from)。

【讨论】:

  • 非常感谢 - 非常有用的解释!正如@Shepmaster 建议的那样,我将问题分为两部分;不要以为您愿意将答案的后半部分移至新问题here?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-26
  • 1970-01-01
  • 2021-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多