由于类型不匹配错误,文本文件解析函数无法编译
Textfile-parsing function fails to compile owing to type-mismatch error
我正在尝试解析一个简单的配置文本文件,其中每行包含一个三词条目,布局如下:
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<&str>
的内容被包裹在 Option
中!
注意。此 post 最初包含两个问题(我认为是一个错误以不同的方式表现出来),但根据评论中的建议,我将其拆分为两个单独的 post。后面的post就是.
您原来的问题只是在循环体的末尾有一个非 ()
表达式。您的 match
表达式的类型为 Option<&str>
(因为那是 HashMap::insert
的 return 类型),而不是类型 ()
。这个问题只要在匹配表达式后面加一个分号就可以解决:
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,
};
For the latter, isn't word_vector populated with owned objects that don't point to line_slice?
不,这正是问题所在。 word_vector
包含 &str
类型的元素,即借用的字符串。这些指向 line_slice
,它只存在到当前循环迭代结束。在将它们插入地图之前,您可能希望将它们转换为 String
s(使用 String::from
)。
我正在尝试解析一个简单的配置文本文件,其中每行包含一个三词条目,布局如下:
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<&str>
的内容被包裹在 Option
中!
注意。此 post 最初包含两个问题(我认为是一个错误以不同的方式表现出来),但根据评论中的建议,我将其拆分为两个单独的 post。后面的post就是
您原来的问题只是在循环体的末尾有一个非 ()
表达式。您的 match
表达式的类型为 Option<&str>
(因为那是 HashMap::insert
的 return 类型),而不是类型 ()
。这个问题只要在匹配表达式后面加一个分号就可以解决:
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,
};
For the latter, isn't word_vector populated with owned objects that don't point to line_slice?
不,这正是问题所在。 word_vector
包含 &str
类型的元素,即借用的字符串。这些指向 line_slice
,它只存在到当前循环迭代结束。在将它们插入地图之前,您可能希望将它们转换为 String
s(使用 String::from
)。