当前位置: 首页 > 知识库问答 >
问题:

为什么Rust NLL不适用于同一语句中的多个借款

沈德寿
2023-03-14

首先,我尝试了这样的方法:

let mut vec = vec![0];
vec.rotate_right(vec.len());

它不能被编译,因为不能借用'vec'作为不可变的,因为它也被借用为可变的

我想这个样本可以解决这个问题

let mut vec = vec![0];
vec.resize(vec.len(), 0);

它可以工作,但是为什么它现在与rotate_right一起工作?

共有2个答案

柳胜
2023-03-14

这两个调用之间唯一的结构差异是目标:rotate_right()在切片上定义,而resize()Vec定义。这意味着非工作案例具有额外的Deref强制(在本例中为DerefMut)必须通过借用检查器。

这实际上超出了非词汇生存期规则的范畴,因为引用的生存时间并不重要。这种好奇心属于评估顺序规则;更具体地说,给定vec。向右旋转(vec.len()),从

函数和方法调用的求值顺序是从左到右,因此强制必须在其他参数之前求值,这意味着vec已经在vec之前可变地借用了。调用len()

钦永贞
2023-03-14

肯定很有趣。

它们相似,但不完全相同。保留()Vec的成员。另一方面,rotate_right()是一种切片方法。

<代码>Vec

vec.resize(vec.len(), 0);

Desugars到类似的东西:

<Vec<i32>>::resize(&mut vec, <Vec<i32>>::len(&vec), 0);

这个电话:

vec.rotate_right(vec.len());

更像是:

<[i32]>::rotate_right(
    <Vec<i32> as DerefMut>::deref_mut(&mut vec),
    <Vec<i32>>::len(&vec),
);

但顺序是什么?

这是rotate_right()的MIR(简化了很多):

fn foo() -> () {
    _4 = <Vec<i32> as DerefMut>::deref_mut(move _5);
    _6 = Vec::<i32>::len(move _7);
    _2 = core::slice::<impl [i32]>::rotate_right(move _3, move _6);
}

这是resize()的MIR(同样,简化了很多):

fn foo() -> () {
    _4 = Vec::<i32>::len(move _5);
    _2 = Vec::<i32>::resize(move _3, move _4, const 0_i32);
}

resize()示例中,我们首先调用Vec::len(),并引用Vec。这将返回usize。然后我们调用Vec::resize(),当我们没有未完成的对Vec的引用时,可以灵活地借用它!

然而,使用rotate_right(),我们首先调用

这是因为Rust定义了操作数的求值顺序:

采用多个操作数的表达式按照源代码中的说明从左到右求值。

因为vec。resize()实际上是(

let dereferenced_vec = &mut *vec;
let len = vec.len();
dereferencec_vec.rotate_right(len);

这显然违反了借款规则。

另一方面,vec.resize(vec.len())在被调用方(vec)上没有工作可做,因此我们首先评估vec.len(),然后评估调用本身。

解决这个问题就像提取vec一样简单。len()到一个新行(准确地说是新语句),编译器也建议这样做。

 类似资料:
  • 首先,我试过这样的方法: 它不能被编译,因为 不能将“vec”作为不可变项借用,因为它也是作为可变项借用的 我认为Rust借用检查器可以比这更聪明,所以我找到了一个叫做NLL的东西,它应该可以解决这个问题。 我试过样本: 它可以工作,但为什么它现在使用的是?他们俩都吃了一顿饭

  • 问题内容: 语句的用途是什么? 问题答案: 它是一种以互斥形式构建的Java。这用于多线程应用程序。 Sun并发教程 这部分有一个关于同步的部分,但是如果您尝试使用多线程应用程序,则应该阅读整个内容。 维基互斥

  • 我是一个学习如何在android上编码的模拟人,所以如果这个问题听起来很愚蠢,请容忍我。 我理解同步的要点。如果我有两个线程都可以访问和修改的数据,这可能会导致两个线程中数据变量的值不一致。 使方法同步并锁定它们直到一个线程执行完它(执行任何条件检查)是有意义的,但是为什么它与单个语句有关系呢?这对于多条语句来说很重要,因为在两条或更多条语句之间,线程一有可能会脱离可运行状态,但是我不明白一条语句

  • 我目前正在修复别人的Java代码中的一个bug,但我无法解释这个bug。所讨论的代码是下面的if语句: 其中初始化为和函数如下所示: 令我困惑的是,即使被设置为false,代码仍然调用并执行函数。我一直认为这是不应该发生的短路。if语句本身总体上仍然被计算为false,因为只有第一个代码段中的else-block中的代码被执行。 那么,这个if语句为什么会有这样的行为呢?是短路失败,还是我误解了原

  • 问题内容: 我试图在PHP的一次调用中发出多个INSERT语句。问题是我得到了这个错误: 我猜这是每个声明之后。 所以现在,我的问题是如何制作多个可以在其中运行的INSERT语句? 到目前为止,这是我的查询: 编辑 : 请注意,由于我使用的是SQL语句,因此查询末尾没有任何内容。 问题答案: 只需将所有语句包装到匿名PL / SQL块中即可: Oracle不支持批量命令。匿名PL / SQL块作为

  • 问题内容: 假设我有这个模型: 现在,如果我想高效地查看相册中的一部分照片。我这样做是这样的: 这只会执行两个查询,这正是我所期望的(一个查询得到相册,然后一个查询,例如“ SELECT * IN photos WHERE photoalbum_id IN()”。 一切都很棒。 但是,如果我这样做: 然后用!进行大量查询!我是在做错什么,还是django不够聪明,以至于它已经获取了所有照片并可以在