gpt4 book ai didi

rust - 错误 : `line` does not live long enough but it's ok in playground

转载 作者:行者123 更新时间:2023-11-29 08:16:47 26 4
gpt4 key购买 nike

我不明白为什么我的本地 var 行没有足够长的时间。你可以在下面看到我的代码。它在 Rust 的 Playground 上工作。

我可能对这个问题有一个想法:我使用一个结构(加载是这个结构的函数)。因为我想将行的结果存储在我的结构的成员中,所以这可能是问题所在。但我不知道我应该怎么做才能解决这个问题。

pub struct Config<'a> {
file: &'a str,
params: HashMap<&'a str, &'a str>
}

impl<'a> Config<'a> {
pub fn new(file: &str) -> Config {
Config { file: file, params: HashMap::new() }
}

pub fn load(&mut self) -> () {
let f = match fs::File::open(self.file) {
Ok(e) => e,
Err(e) => {
println!("Failed to load {}, {}", self.file, e);
return;
}
};
let mut reader = io::BufReader::new(f);
let mut buffer = String::new();

loop {
let result = reader.read_line(&mut buffer);

if result.is_ok() && result.ok().unwrap() > 0 {
let line: Vec<String> = buffer.split("=").map(String::from).collect();

let key = line[0].trim();
let value = line[1].trim();

self.params.insert(key, value);
}

buffer.clear();
}
}
...
}

我得到这个错误:

src/conf.rs:33:27: 33:31 error: `line` does not live long enough
src/conf.rs:33 let key = line[0].trim();
^~~~
src/conf.rs:16:34: 41:6 note: reference must be valid for the lifetime 'a as defined on the block at 16:33...
src/conf.rs:16 pub fn load(&mut self) -> () {
src/conf.rs:17 let f = match fs::File::open(self.file) {
src/conf.rs:18 Ok(e) => e,
src/conf.rs:19 Err(e) => {
src/conf.rs:20 println!("Failed to load {}, {}", self.file, e);
src/conf.rs:21 return;
...
src/conf.rs:31:87: 37:14 note: ...but borrowed value is only valid for the block suffix following statement 0 at 31:86
src/conf.rs:31 let line: Vec<String> = buffer.split("=").map(String::from).collect();
src/conf.rs:32
src/conf.rs:33 let key = line[0].trim();
src/conf.rs:34 let value = line[1].trim();
src/conf.rs:35
src/conf.rs:36 self.params.insert(key, value);
...

最佳答案

要了解为什么这不起作用,需要三个步骤。

let line: Vec<String> = buffer.split("=").map(String::from).collect();
let key = line[0].trim();
let value = line[1].trim();
self.params.insert(key, value);
  1. lineVecString s,表示向量拥有其包含的字符串。这样做的一个效果是,当 vector 从内存中释放时,元素、字符串也被释放。
  2. 如果我们看一下 string::trim here ,我们看到它接受并返回一个 &str .换句话说,该函数不分配任何东西,也不转移所有权——它返回的字符串只是原始字符串的一部分。因此,如果我们要释放原始字符串,修剪后的字符串将没有有效数据。

  3. HashMap::insert的签名是fn insert(&mut self, k: K, v: V) -> Option<V> .该函数同时移动键和值,因为只要它们在 HashMap 中,它们就需要有效。我们想给 hashmap 两个字符串。然而,keyvalue只是对向量拥有的字符串的引用——我们只是借用它们——所以我们不能放弃它们。

解决方法很简单:拆分后复制字符串。

let line: Vec<String> = buffer.split("=").map(String::from).collect();
let key = line[0].trim().to_string();
let value = line[1].trim().to_string();
self.params.insert(key, value);

这将分配两个新字符串,并将修剪后的切片复制到新字符串中。


如果我们之后不修剪字符串,我们可以将字符串移出向量(即使用 Vec::remove );在不分配新字符串的情况下,我无法找到一种简单的方法来修剪字符串。

此外,正如 malbarbo 提到的,我们可以避免使用 map(String::from) 完成的额外分配。 ,并使用 collect() 创建向量, 通过简单地省略它们。

关于rust - 错误 : `line` does not live long enough but it's ok in playground,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36949184/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com