由于 lifetime/borrow 错误,文本文件解析函数无法编译
Textfile-parsing function fails to compile owing to lifetime/borrow error
注意。这个 post 最初是一个更大的 post 的一部分,它包含两个问题(我认为是一个错误以不同的方式表现出来),但为了遵守网站指南,我将它分成两个单独的 posts,这是第二个。第一个 post 是 .
我正在尝试解析一个简单的配置文本文件,其中每行包含一个三词条目,布局如下:
ITEM name value
ITEM name value
//etc.
我在此处(和 on the Rust playground)重现了执行解析(以及随后的编译错误)的函数:
use std::fs::File;
use std::io::prelude::*;
use std::io::BufReader;
use std::path::Path;
use std::collections::HashMap;
fn main() { }
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; }
// no match statement
connection_map.insert(word_vector[1], word_vector[2]);
}
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>,
}
<anon>:20:38: 20:48 error: `line_slice` does not live long enough
<anon>:20 let word_vector: Vec<&str> = line_slice.split_whitespace().collect();
^~~~~~~~~~
note: in expansion of for loop expansion
<anon>:17:5: 26:6 note: expansion site
<anon>:9:44: 29:2 note: reference must be valid for the anonymous lifetime #1 defined on the block at 9:43...
<anon>:9 pub fn parse(path: &Path) -> config_struct {
<anon>:10
<anon>:11 let file = File::open(&path).unwrap();
<anon>:12 let reader = BufReader::new(&file);
<anon>:13 let line_iterator = reader.lines();
<anon>:14 let mut connection_map = HashMap::new();
...
<anon>:19:40: 26:6 note: ...but borrowed value is only valid for the block suffix following statement 0 at 19:39
<anon>:19 let line_slice = line.unwrap();
<anon>:20 let word_vector: Vec<&str> = line_slice.split_whitespace().collect();
<anon>:21
<anon>:22 if word_vector.len() != 3 { continue; }
<anon>:23
<anon>:24 // no match statement
...
error: aborting due to previous error
本质上,我在使用借用检查器时遇到了问题;在我的代码中,不是 word_vector
填充了不指向 line_slice
的拥有对象吗?我想也许 unwrap()
或 collect()
返回了一个引用并且它是超出范围的引用,但是 unwrap and collect 的 Rust 文档建议否则。
一个&str
如果没有存储它包含的值的东西就不可能存在——它纯粹是一个引用(因此&
)。
从文件中读取您得到 String
s; 这些 提供存储空间。但是你正在放弃它们,试图只 return 字符串。
也可以这样想:
pub fn parse(path: &Path) -> config_struct<'???>;
return 值的寿命应该是多少?
它没有抱怨那部分的唯一原因是它推断 Path
引用生命周期和 return 值生命周期相同,这意味着你是 return引用 Path
中的内容,而你不是。
在这种情况下,您通常需要存储 String
而不是 &str
。使用 .to_owned()
.
将每个 &str
转换为 String
注意。这个 post 最初是一个更大的 post 的一部分,它包含两个问题(我认为是一个错误以不同的方式表现出来),但为了遵守网站指南,我将它分成两个单独的 posts,这是第二个。第一个 post 是
我正在尝试解析一个简单的配置文本文件,其中每行包含一个三词条目,布局如下:
ITEM name value
ITEM name value
//etc.
我在此处(和 on the Rust playground)重现了执行解析(以及随后的编译错误)的函数:
use std::fs::File;
use std::io::prelude::*;
use std::io::BufReader;
use std::path::Path;
use std::collections::HashMap;
fn main() { }
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; }
// no match statement
connection_map.insert(word_vector[1], word_vector[2]);
}
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>,
}
<anon>:20:38: 20:48 error: `line_slice` does not live long enough
<anon>:20 let word_vector: Vec<&str> = line_slice.split_whitespace().collect();
^~~~~~~~~~
note: in expansion of for loop expansion
<anon>:17:5: 26:6 note: expansion site
<anon>:9:44: 29:2 note: reference must be valid for the anonymous lifetime #1 defined on the block at 9:43...
<anon>:9 pub fn parse(path: &Path) -> config_struct {
<anon>:10
<anon>:11 let file = File::open(&path).unwrap();
<anon>:12 let reader = BufReader::new(&file);
<anon>:13 let line_iterator = reader.lines();
<anon>:14 let mut connection_map = HashMap::new();
...
<anon>:19:40: 26:6 note: ...but borrowed value is only valid for the block suffix following statement 0 at 19:39
<anon>:19 let line_slice = line.unwrap();
<anon>:20 let word_vector: Vec<&str> = line_slice.split_whitespace().collect();
<anon>:21
<anon>:22 if word_vector.len() != 3 { continue; }
<anon>:23
<anon>:24 // no match statement
...
error: aborting due to previous error
本质上,我在使用借用检查器时遇到了问题;在我的代码中,不是 word_vector
填充了不指向 line_slice
的拥有对象吗?我想也许 unwrap()
或 collect()
返回了一个引用并且它是超出范围的引用,但是 unwrap and collect 的 Rust 文档建议否则。
一个&str
如果没有存储它包含的值的东西就不可能存在——它纯粹是一个引用(因此&
)。
从文件中读取您得到 String
s; 这些 提供存储空间。但是你正在放弃它们,试图只 return 字符串。
也可以这样想:
pub fn parse(path: &Path) -> config_struct<'???>;
return 值的寿命应该是多少?
它没有抱怨那部分的唯一原因是它推断 Path
引用生命周期和 return 值生命周期相同,这意味着你是 return引用 Path
中的内容,而你不是。
在这种情况下,您通常需要存储 String
而不是 &str
。使用 .to_owned()
.
&str
转换为 String