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

为什么Rust NLL不适用于同一报表中的多笔借款

仲元凯
2023-03-14

首先,我试过这样的方法:

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

它不能被编译,因为

不能将“vec”作为不可变项借用,因为它也是作为可变项借用的

我认为Rust借用检查器可以比这更聪明,所以我找到了一个叫做NLL的东西,它应该可以解决这个问题。

我试过样本:

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

它可以工作,但为什么它现在使用的是rotate_right?他们俩都吃了一顿饭

共有2个答案

金宣
2023-03-14

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

这实际上超出了非词汇生存期规则的范围,因为引用存在多长时间并不重要。这种好奇心将属于求值顺序规则;更具体地说,给定vec.rotate_right(vec.len()),来自的强制何时

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

胡云瀚
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()到一个新行(准确地说是新语句),编译器也建议这样做。

 类似资料:
  • 首先,我尝试了这样的方法: 它不能被编译,因为 我想这个样本可以解决这个问题 它可以工作,但是为什么它现在与一起工作?

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

  • https://godbolt.org/z/P97MaK 我玩的概念和预期d::is_equality_comparable工作矢量,但它没有。 编译错误在 内部失败,而不是在受概念保护的函数边界处失败。 这是错误还是预期行为?

  • 为什么只适用于s而不适用于s?有什么特别的原因吗?

  • 我在更新链式lodash操作时遇到了这个问题,我不明白为什么会有不同的效果 我把范围缩小到用链子把一根forEach拴在一个lodash包装纸上 https://jsbin.com/wahokezeja/edit?js,控制台 这将抛出一个错误: “TypeError:\(…)。forEach(…)。groupBy不是一个函数 但是,当使用贴图链接时,效果很好 https://jsbin.com/

  • 我一直在收到com。谷歌。格森。JsonSyntaxException无法调用Gson。fromJson(),因此添加了一个捕获(异常)逻辑,但错误永远不会被捕获,而只是被抛出! 这是我所拥有的: 运行测试时,我得到“com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:应为BEGIN\u对象,但在第1行第1列路径$