为什么编译器告诉我考虑使用“let"绑定?当我已经是? [英] Why does the compiler tell me to consider using a `let` binding" when I already am?

查看:33
本文介绍了为什么编译器告诉我考虑使用“let"绑定?当我已经是?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的错误是什么以及如何解决?

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 type Vec<i8>.
    • We make the call .iter(). Surprisingly, Vec<i8> has no iter 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 the Deref trait, and applies it if necessary. Vec<i8> does implement Deref, so we implicitly call its deref method. However, deref takes its self argument by reference, which means that get_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 an iter method. Finally! This iter also takes its self argument by reference, and returns a std::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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆