在调用`drop`之后,移动变量仍在借用吗? [英] Moved variable still borrowing after calling `drop`?

查看:63
本文介绍了在调用`drop`之后,移动变量仍在借用吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

fn main() {
    let mut x: Vec<&i32> = vec![];
    let a = 1;
    x.push(&a);
    drop(x);
    // x.len(); // error[E0382]: use of moved value: `x`
}  // `a` dropped here while still borrowed

编译器知道drop()会丢弃x(从注释代码中的错误可以明显看出),但仍然认为该变量是从a借来的!这不公平!

The compiler knows drop() drops x (as evident from the error in the commented-out code) but still thinks the variable is borrowing from a! This is unfair!

应该将其视为 rust-lang/rust#6393的众多骗子之一(现在被 rust-lang/rfcs#811 ?),但是那里的讨论似乎集中在使&mut self&self共存于一个块中.

Should this be considered as one of numerous dupes of rust-lang/rust#6393 (which is now tracked by rust-lang/rfcs#811?) But the discussion there seems to be centered on making &mut self and &self coexist in a single block.

推荐答案

我不能给您确切的答案,但是我会在这里尝试解释一些事情.让我们从澄清一些事情开始:

I can't give you a definite answer, but I'll try to explain a few things here. Let's start with clarifying something:

编译器知道drop()丢弃x

这不是事实.尽管标准库中有一些编译器知道的魔术"内容,但是drop()并不是 lang项目.实际上,您可以自己实现drop(),这实际上是最简单的事情:

This is not true. While there are a few "magic" things in the standard library that the compiler knows about, drop() is not such a lang item. In fact, you could implement drop() yourself and it's actually the easiest thing to do:

fn drop<T>(_: T) {}

该函数仅按值取值(因此,它已移至drop()中),并且由于drop()内部什么也没有发生,因此该值在范围的末尾被删除,就像在其他函数中一样.因此:编译器不知道x被删除,而只是知道x被移动了.

The function just takes something by value (thus, it's moved into drop()) and since nothing happens inside of drop(), this value is dropped at the end of the scope, like in any other function. So: the compiler doesn't know x is dropped, it just knows x is moved.

您可能已经注意到,无论我们是否添加drop()调用,编译器错误均保持不变.现在,当涉及到引用时,编译器只会查看变量的 scope .从 Niko Matsakis的NLL简介:

As you might have noticed, the compiler error stays the same regardless of whether or not we add the drop() call. Right now, the compiler will only look at the scope of a variable when it comes to references. From Niko Matsakis' intro to NLL:

编译器当前的工作方式,将引用分配给变量意味着它的生存期必须与该变量的整个范围一样大.

The way that the compiler currently works, assigning a reference into a variable means that its lifetime must be as large as the entire scope of that variable.

并在随后的博客中他的帖子:

尤其是今天,一旦生存期必须延伸到单个语句的边界之外,它就必须一直延伸到封闭块的末尾.

In particular, today, once a lifetime must extend beyond the boundaries of a single statement [...], it must extend all the way till the end of the enclosing block.

这正是这里发生的情况,所以是的,您的问题与所有这些词汇借用"有关.从当前的编译器角度来看,表达式&a的生存期至少必须与x的范围一样大.但这是行不通的,因为该引用将超过a,因为x的范围大于编译器指出的a的范围:

This is exactly what happens here, so yes, your problem has to do with all this "lexical borrowing" stuff. From the current compilers perspective, the lifetime of the expression &a needs to be at least as large as the scope of x. But this doesn't work, since the reference would outlive a, since the scope of x is larger than the scope of a as pointed out by the compiler:

= note: values in a scope are dropped in the opposite order they are created

我想您已经知道所有这些,但是您可以通过交换行let mut x ...;let a ...;来修正示例.

And I guess you already know all that, but you can fix your example by swapping the lines let mut x ...; and let a ...;.

我不确定当前提出的任何解决方案是否可以解决这个确切的问题.但是我希望我们能尽快看到,因为所有这些都将作为Rust 2017路线图的一部分得到解决.在此处(其中还包含链接到Niko的五个相关博客文章).

I'm not sure whether or not this exact problem would be solved by any of the currently proposed solutions. But I hope that we will see soon enough, as all of this is being addressed as part of the Rust 2017 roadmap. A good place to read up on the updates is here (which also contains links to the five relevant blog posts of Niko).

这篇关于在调用`drop`之后,移动变量仍在借用吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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