我的错误是什么以及如何解决?
fn get_m() -> Vec<i8> {
vec![1, 2, 3]
}
fn main() {
let mut vals = get_m().iter().peekable();
println!("Saw a {:?}", vals.peek());
}
( playground )
编译器的错误提示“考虑使用 let
绑定(bind)”——但我已经是:
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 ,但不涉及将表达式分解为多个语句,因此我认为问题不相同。
最佳答案
问题是 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
按值(value),所以Iter
被消费了,我们得到一个std::iter::Peekable
作为返回,再次持有对切片的引用。 - 这
Peekable
然后绑定(bind)到变量vals
,它一直存在到函数结束。 - 暂持原
Vec<i8>
, 其元素Peekable
指的是,现在死了。哎呀。这是借来的值(value)不够长。
但是临时工在那里消亡只是因为这是临时工的规则。如果我们给它一个名字,那么只要它的名字在范围内,它就会持续存在:
let vec = get_m();
let mut peekable = vec.iter().peekable();
println!("Saw a {:?}", vals.peek());
我想这就是故事。然而,仍然让我感到困惑的是,为什么即使没有名字,临时工也不会活得更久。 Rust 引用说,“一个临时对象的生命周期等于任何指向它的引用的最大生命周期。”但这里显然不是这种情况。
关于rust - 为什么编译器告诉我考虑使用 `let` 绑定(bind)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28893183/