下面的代码:
fn main() {
let mut v = vec![1, 2, 3];
for _ in v.iter() {
v[0] = 0;
// return;
}
}
它不能编译,我知道为什么了,因为我试图同时拥有v
的共享(v.iter()
)和可变(v[0] = 0
)引用。
然而,取消注解return
语句会使代码编译,我不知道为什么,我猜编译器不知何故设法知道在可变借位发生之前可以删除对v
的共享引用,但它是如何确切地知道这一点的呢?
在本例中,v
的两次借用的生存期是多少?
1条答案
按热度按时间2wnc66cl1#
for
循环只是带有手动迭代器的循环的语法糖:相当于:
因此,对于原始代码,它将是:
(The这里对
into_iter()
的调用是多余的,因为将其与迭代器一起使用只会返回自身。)正如预期的那样,这段代码和您的代码一样失败。
但是如果您取消对返回的注解,那么编译器就知道循环永远不会重复,因此它被转换为:
现在,* 非词法生存期(NLL)*,并看到
iterator
在调用next()
之外没有被使用,因此可以将其删除。_
不算在内,因为它不是真实的的绑定,但即使您改为编写_x
,NLL会立即丢弃它,因为它不再被使用,因此v
不再是借用的,对v[0]
的赋值是完全安全和法律的的。如果您保持
v
的原始借位有效,它将再次失败:这个失败有一个很好的解释: