tl;drerror[E0716]: temporary value dropped while borrowed是一个困难且常见的问题,有一致的解决方案吗?
我遇到了困难的 rustc 错误
error[E0716]: temporary value dropped while borrowed
...
creates a temporary which is freed while still in use
Run Code Online (Sandbox Code Playgroud)
搜索Stackoverflow,有很多关于这个rust error的问题error[E0716]。
也许 Rust 专家可以为这个常见的新手问题提供一个通用的解决方案,一个足够好的解决方案,它也可以回答链接的问题(见下文)。
一个简洁的代码示例来演示该问题(Rust Playground):
type Vec1<'a> = Vec::<&'a String>;
fn fun1(s1: &String, v1: &mut Vec1) {
v1.insert(0, &s1.clone());
}
fn main() {
let mut vec1 = Vec::new();
let str1 = String::new();
fun1(&str1, &mut vec1);
}
Run Code Online (Sandbox Code Playgroud)
结果:
error[E0716]: temporary value dropped while borrowed
--> src/main.rs:4:19
|
3 | fn fun1(s1: &String, v1: &mut Vec1) {
| -- has type `&mut Vec<&'1 String>`
4 | v1.insert(0, &s1.clone());
| --------------^^^^^^^^^^-- temporary value is freed at the end of this statement
| | |
| | creates a temporary which is freed while still in use
| argument requires that borrow lasts for `'1`
For more information about this error, try `rustc --explain E0716`.
Run Code Online (Sandbox Code Playgroud)
我的理解是v1.insert(0, &s1.clone());,
会使用堆作为存储s1.clone()来创建一个新的。String然后,新克隆的String(添加的&)引用被传递给 call v1.insert。因此,新String数据和传递给的引用insert将在函数fun1返回后保留。
但 Rust 编译器报告s1.clone()只是暂时的。
以下是类似问题的链接,该问题的版本并不总是相同,但有些更麻烦和冗长(IMO)。
我对链接到该问题的这些问题添加了评论。
你的问题确实是在编译指示的行上。我们稍微分析一下:
fn fun1(s1: &String, v1: &mut Vec1) {
v1.insert(0, &s1.clone());
}
Run Code Online (Sandbox Code Playgroud)
你的理解不太正确。让我们看看插入的签名:
pub fn insert(&mut self, index: usize, element: T)
Run Code Online (Sandbox Code Playgroud)
类型T意味着它按值捕获,因此调用后不会使用元素。您只需通过将向量设置为Vec<&String>而不是Vec<String>来对此进行调整。
结果:您想要插入对字符串克隆的引用
操作方法:克隆并插入引用
rust 的引用和 C/C++ 指针之间的区别在于,rust 不允许引用指向已释放的数据(它们必须始终指向有效数据)。当您克隆字符串时,您会创建它的副本,但该副本仅在fun1的生命周期内可用。当对fun1 的调用结束时,克隆的字符串将被删除,因为该函数拥有该克隆,因此它负责清理它(rust 的基于所有权的资源管理)。
在 C++ 中,这是有效的:您可以分配一个指针并将该指针推入向量中,但 Rust 不允许这样的事情。
你的fun1相当于这个:
fn fun1(s1: &String, v1: &mut Vec1) {
let im_tmp = s1.clone();
v1.insert(0, &im_tmp);
}
Run Code Online (Sandbox Code Playgroud)
类似的操作应该始终敲响警钟,因为im_tmp将被清除。要解决您的问题:
type Vec1<'a> = Vec::<String>;
fn fun1(s1: &String, v1: &mut Vec1) {
v1.insert(0, s1.clone());
}
fn main() {
let mut vec1 = Vec::new();
let str1 = String::new();
fun1(&str1, &mut vec1);
println!("{:?}", vec1);
}
Run Code Online (Sandbox Code Playgroud)
该类型不再是引用向量,而是实际对象。在fun1中,向量获得克隆字符串的所有权。
向量具有您创建的类型的另一个示例是这个,但这是有效的,因为编译器可以推断克隆字符串的生命周期。请注意,如果您执行vec1.insert(0, &str1.clone())将不起作用,因为对克隆的引用仅在调用 insert 的生命周期内可用:
type Vec1<'a> = Vec::<&'a String>;
fn main() {
let mut vec1 = Vec::new();
let str1 = String::new();
let clone = str1.clone();
vec1.insert(0, &clone);
println!("{:?}", vec1);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2408 次 |
| 最近记录: |