Cab*_*ero 3 lifetime rust borrow-checker
为什么会to_string()导致borrowed value does not live long enough错误?下面的例子:
use std::collections::HashMap;
struct Foo {
id: Option<usize>,
name: String
}
fn main() {
let foos = getFoos();
for foo in foos {
let mut map = HashMap::new();
map.insert("name", &foo.name);
map.insert("id", &foo.id.unwrap().to_string());
}
}
fn getFoos() -> Vec<Foo> {
Vec::new()
}
Run Code Online (Sandbox Code Playgroud)
错误:
src/main.rs:15:27: 15:54 error: borrowed value does not live long enough
src/main.rs:15 map.insert("id", &foo.id.unwrap().to_string());
^~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.rs:13:38: 16:6 note: reference must be valid for the block suffix following statement 0 at 13:37...
src/main.rs:13 let mut map = HashMap::new();
src/main.rs:14 map.insert("name", &foo.name);
src/main.rs:15 map.insert("id", &foo.id.unwrap().to_string());
src/main.rs:16 }
src/main.rs:15:9: 15:56 note: ...but borrowed value is only valid for the statement at 15:8
src/main.rs:15 map.insert("id", &foo.id.unwrap().to_string());
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.rs:15:9: 15:56 help: consider using a `let` binding to increase its lifetime
src/main.rs:15 map.insert("id", &foo.id.unwrap().to_string());
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
为什么编译器建议创建中间值?这个错误令人困惑。
您正在创建一个HashMap保存对字符串的引用,即&String. 如果我们要注释类型,它看起来像这样:
let mut map: HashMap<&str, &String> = HashMap::new();
Run Code Online (Sandbox Code Playgroud)
这意味着地图包含大量对位于其他地方的对象的引用。在您的第一个插入中,这工作得很好,因为foo.name位于其他地方,特别是在 object 中foo。
map.insert("name", &foo.name);
Run Code Online (Sandbox Code Playgroud)
但是你的第二个插入有一个问题:你想引用一个位于String某处的对象。to_string()创建String由函数返回的a ,但在您的情况下它只是一个临时对象。该行执行后对象将被销毁。
map.insert("id", &foo.id.unwrap().to_string());
Run Code Online (Sandbox Code Playgroud)
编译器是对的:let绑定可以解决这里的问题。
let mut map = HashMap::new();
map.insert("name", &foo.name);
let id_string = foo.id.unwrap().to_string();
map.insert("id", &id_string);
Run Code Online (Sandbox Code Playgroud)
这在您的小示例中运行良好,但是当您处理更大的事情时可能会更复杂。例如,如果HashMap将在循环之外定义,则会出现问题,因为您插入到地图中的引用需要至少与地图本身一样长。
| 归档时间: |
|
| 查看次数: |
496 次 |
| 最近记录: |