无法理解Rust中‘borrowed value does not live long enough’错误求解释
Rust中向Vec<&str>推送循环内&str的生命周期问题
我在循环中尝试向Vec<&str>类型的向量推送&str时遇到了生命周期错误,相关代码如下:
use std::io; fn main() { let mut accounting = vec!["Alice", "Ben"]; loop { let mut add_input = String::from(""); io::stdin() .read_line(&mut add_input) .expect("Failed to read line"); let add_vec: Vec<&str> = add_input.trim()[..].split_whitespace().collect(); if add_vec.len() < 1 { println!("Incorrect input, try again"); continue; } let person = add_vec[0]; accounting.push(person); } }
编译时在let add_vec: Vec<&str> = add_input.trim()[..].split_whitespace().collect();行报错,错误为“borrowed value does not live long enough”。我通过将目标向量签名从Vec<&str>改为Vec<String>,并推送person.to_string()让代码正常运行,但疑惑:既然推送操作在循环末尾,为何还会出现这个问题?完整编译错误信息如下:
$ rustc main.rs error[E0597]: `add_input` does not live long enough --> main.rs:14:34 | 14 | let add_vec: Vec<&str> = add_input.trim()[..].split_whitespace().collect(); | ^^^^^^^^^^^^^^^^ borrowed value does not live long enough ... 22 | accounting.push(person); | ----------------------- borrow later used here 23 | } | - `add_input` dropped here while still borrowed error: aborting due to previous error For more information about this error, try `rustc --explain E0597`.
原因分析
add_input是循环内部创建的String,它的生命周期仅局限于当前循环迭代,当一次迭代结束后,add_input会被自动销毁。add_vec中的所有&str都是对add_input内容的引用,当你把person(这些引用之一)推入accounting后,accounting的生命周期是整个main函数,远长于add_input的生命周期。- Rust的借用检查器会严格阻止这种情况发生:如果允许,循环结束后
add_input被销毁,accounting里的引用就会变成悬垂引用,访问它会引发内存安全问题,这是Rust绝对不允许的。
为什么改成Vec<String>可行?
String是拥有所有权的类型,person.to_string()会将引用指向的字符串内容复制一份,生成一个新的、拥有独立所有权的String实例。这个新实例的生命周期和accounting一致,不会出现悬垂引用的问题,因此可以安全地存入向量中。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

