为什么编译器告诉我考虑使用“let"绑定?当我已经是? [英] Why does the compiler tell me to consider using a `let` binding" when I already am?
问题描述
我的错误是什么以及如何解决?
What is my error and how to fix it?
fn get_m() -> Vec<i8> {
vec![1, 2, 3]
}
fn main() {
let mut vals = get_m().iter().peekable();
println!("Saw a {:?}", vals.peek());
}
(游乐场)
编译器的错误提示考虑使用 let
绑定"——但我已经这样做了:
The compiler's error suggests "consider using a let
binding" — but I already am:
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 来处理借用检查器......显然我没有.
This is obviously a newbie question -- though I thought I'd written enough Rust at this point that I had a handle on the borrow checker... apparently I haven't.
这个问题类似于使用`let` 绑定以增加值生命周期,但不涉及将表达式分解为多个语句,因此我认为问题并不相同.
This question is similar to Using a `let` binding to increase value lifetime, but doesn't involve breaking down an expression into multiple statements, so I don't think the problem is identical.
推荐答案
问题是 Peekable
迭代器一直存在到函数的末尾,但它持有对 Peekable
返回的向量的引用code>get_m,它的持续时间与包含该调用的语句一样长.
The problem is that the Peekable
iterator lives to the end of the function, but it holds a reference to the vector returned by get_m
, which only lasts as long as the statement containing that call.
这里实际上发生了很多事情,所以让我们一步一步来:
There are actually a lot of things going on here, so let's take it step by step:
get_m
分配并返回一个类型为Vec
的向量.- 我们调用
.iter()
.令人惊讶的是,Vec
没有iter
方法,也没有实现任何具有的 trait.所以这里有三个子步骤:- 任何方法调用都会检查其
self
值是否实现了Deref
特性,并在必要时应用它.Vec
确实实现了Deref
,所以我们隐式调用了它的deref
方法.但是,deref
以引用的方式接受其self
参数,这意味着get_m()
现在是出现在左值上下文中的右值.在这种情况下,Rust 会创建一个临时对象来保存值,并传递对该值的引用.(注意这个临时的!) - 我们调用
deref
,产生一个&[i8]
类型的切片,借用向量的元素. - 这个切片实现了
SliceExt
trait,它确实有一个iter
方法.最后!这个iter
也通过引用接受它的self
参数,并返回一个std::slice::Iter
保存对切片的引用.立>
get_m
allocates and returns a vector, of typeVec<i8>
.- We make the call
.iter()
. Surprisingly,Vec<i8>
has noiter
method, nor does it implement any trait that has one. So there are three sub-steps here:- Any method call checks whether its
self
value implements theDeref
trait, and applies it if necessary.Vec<i8>
does implementDeref
, so we implicitly call itsderef
method. However,deref
takes itsself
argument by reference, which means thatget_m()
is now an rvalue appearing in an lvalue context. In this situation, Rust creates a temporary to hold the value, and passes a reference to that. (Keep an eye on this temporary!) - We call
deref
, yielding a slice of type&[i8]
borrowing the vector's elements. - This slice implements the
SliceExt
trait, which does have aniter
method. Finally! Thisiter
also takes itsself
argument by reference, and returns astd::slice::Iter
holding a reference to the slice.
但是临时工会死在那里只是因为这是临时工的规则.如果我们给它一个名字,那么只要它的名字在范围内,它就会持续:
But the temporary dies there only because that's the rule for temporaries. If we give it a name, then it lasts as long as its name is in scope:
let vec = get_m(); let mut peekable = vec.iter().peekable(); println!("Saw a {:?}", vals.peek());
我认为这就是故事.然而,仍然让我困惑的是,为什么即使没有名字,那个临时的也不会活得更久.Rust 引用说,临时的生命周期等于指向它的任何引用的最大生命周期."但这里显然不是这种情况.
I think that's the story. What still confuses me, though, is why that temporary doesn't live longer, even without a name. The Rust reference says, "A temporary's lifetime equals the largest lifetime of any reference that points to it." But that's clearly not the case here.
这篇关于为什么编译器告诉我考虑使用“let"绑定?当我已经是?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- Any method call checks whether its
- 任何方法调用都会检查其