gpt4 book ai didi

rust - 无法在用户定义类型的 `Vec` 内添加分配

转载 作者:行者123 更新时间:2023-12-04 11:03:00 26 4
gpt4 key购买 nike

考虑这个代码( Rust Playground ):

#[derive(Clone, Copy, Debug)]
struct X(i32);

impl std::ops::AddAssign for X {
fn add_assign(&mut self, rhs: Self) {
self.0 += rhs.0;
}
}

fn main() {
let mut ary_i32 = [1_i32; 2];
ary_i32[0] += ary_i32[1]; // OK

let mut ary_x = [X(1); 2];
ary_x[0] += ary_x[1]; // OK

let mut vec_i32 = vec![1_i32; 2];
vec_i32[0] += vec_i32[1]; // OK

let mut vec_x = vec![X(1); 2];
vec_x[0] += vec_x[1]; // error[E0502]: cannot borrow `vec_x` as immutable because it is also borrowed as mutable
}

为什么我只在 vec_x 上收到 E0502线?
我不明白为什么只有 ary_x 的操作和 vec_i32被允许。借用检查器是否特别处理内置类型( i32array )?

最佳答案

我研究了一些资源并阅读了我的代码的 MIR,并设法了解发生了什么。
comment @trentcl 将是最好的答案。
我尽量写详细。
对于 array , IndexIndexMut不使用特征,编译器直接操作数组元素(您可以通过 MIR 看到这一点)。所以,这里不存在借贷问题。
解释Vec , rustc guide很有用。
一、Two-phase borrow不适用于 vec_foo[0] += vec_foo[1]陈述。
而且,i32之间的区别和 X是由 operator lowering 引起的.
基本上,像 vec_user_defined[0] += vec_user_defined[1] 这样的语句转换为函数调用,如 add_assign(index_mut(...), *index(...)) , 和函数参数从左到右计算。所以,index_mut()x可变和 index()试图借x ,并失败。
但是对于像 i32 这样的内置类型,复合赋值运算符不会转换为函数调用,并且在lhs之前评估rhs(您可以看到index()index_mut()之前使用MIR调用)。因此,对于内置类型,vec_builtin[0] += vec_builtin[1]作品。
我从 lo48576's article 知道这些事情(日本人)。
我考虑了一些解决方法:

  • 只需使用中间变量作为@sebpuetz said .
  • 转换 Vecslice作为@trentcl said .但这不适用于多维 Vec .
  • 编写一些宏来自动引入一个中间变量。我找到了 rhs_first_assign crate 做这样的工作。
  • 关于rust - 无法在用户定义类型的 `Vec` 内添加分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67200596/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com