我的错误是什么以及如何解决?
fn get_m() -> Vec<i8> {
vec![1, 2, 3]
}
fn main() {
let mut vals = get_m().iter().peekable();
println!("Saw a {:?}", vals.peek());
}
编译器的错误表明“考虑使用let
绑定” - 但我已经是:
error[E0597]: borrowed value does not live long enough
--> src/main.rs:6:45
|
6 | let mut vals = get_m().iter().peekable();
| ------- ^ temporary value dropped here while still borrowed
| |
| temporary value created here
7 | println!("Saw a {:?}", vals.peek());
8 | }
| - temporary value needs to live until here
|
= note: consider using a `let` binding to increase its lifetime
这显然是一个新手问题 - 尽管我认为我已经写了足够的Rust,我已经掌握了借阅检查器...显然我没有。
此问题与Using a `let` binding to increase value lifetime类似,但不涉及将表达式分解为多个语句,因此我认为问题不一致。
答案 0 :(得分:7)
问题是Peekable
迭代器存在于函数的末尾,但是它保存了对get_m
返回的向量的引用,该向量只持续与包含该调用的语句一样长。
这里实际上发生了很多事情,所以让我们一步一步地采取行动:
get_m
分配并返回Vec<i8>
类型的向量。.iter()
。令人惊讶的是,Vec<i8>
没有iter
方法,也没有实现任何具有一个特征的特征。所以这里有三个子步骤:
self
值是否实现Deref
特征,并在必要时应用它。 Vec<i8>
确实实现了Deref
,因此我们隐式调用其deref
方法。但是,deref
通过引用获取其self
参数,这意味着get_m()
现在是左值上下文中出现的右值。在这种情况下,Rust会创建一个临时值来保存该值,并将引用传递给该值。 (留意这暂时!)deref
,产生一个&[i8]
类型的片段借用向量的元素。SliceExt
特征, 具有iter
方法。最后!此iter
也通过引用获取其self
参数,并返回一个std::slice::Iter
,其中包含对切片的引用。.peekable()
。和以前一样,std::slice::Iter
没有peekable
方法,但确实实现了Iterator
;每个IteratorExt
都会实施Iterator
;并且IteratorExt
具有peekable
方法。这需要self
的值,因此消耗了Iter
,然后我们得到一个std::iter::Peekable
返回,再次保持对切片的引用。Peekable
绑定到变量vals
,该变量位于函数的末尾。Vec<i8>
指向的元素的原始Peekable
现在已经死亡。哎呀。这是借来的价值不够长。但临时死亡只是因为那是临时的规则。如果我们给它一个名字,那么只要它的名字在范围内就会持续:
let vec = get_m();
let mut peekable = vec.iter().peekable();
println!("Saw a {:?}", vals.peek());
我认为这就是故事。然而,让我感到困惑的是,即使没有名字,临时也不会延长寿命的原因。 Rust引用说,&#34;临时生命周期等于指向它的任何引用的最大生命周期。&#34;但这显然不是这种情况。
答案 1 :(得分:5)
这种情况正在发生,因为您尝试在.iter().peekable()
内的实际向量上运行get_m()
,vals
重新引用该向量。
基本上,你想要这样的东西:
fn get_m() -> Vec<i8> {
vec![1, 2, 3]
}
fn main() {
let vals = get_m();
let mut val = vals.iter().peekable();
println!("Saw a {:?}", val.peek());
}
结果:
Saw a Some(1)