rust - 即使声明为可变的,变量也被认为是不可变的

标签 rust immutability mutable

<分区>

我通过用 bool 值向量表示数字来重新创建二进制算术运算。由于每个向量的大小可能不同,我制作了一个函数来匹配每个向量的长度:

fn match_lengths(mut bit_vec0: Vec<bool>, mut bit_vec1: Vec<bool>) -> (Vec<bool>, Vec<bool>) {
    {
        let (mut shorter, longer) = if bit_vec0.len() < bit_vec1.len() {
            (&bit_vec0, &bit_vec1)
        } else {
            (&bit_vec1, &bit_vec0)
        };
        let bit_sign = match shorter.last() {
            Some(content) => *content,
            None => false,
        };

        for _ in shorter.len()..longer.len() {
            shorter.push(bit_sign);
        }
    }

    (bit_vec0, bit_vec1)
}

我得到了错误

error[E0596]: cannot borrow immutable borrowed content `*shorter` as mutable
  --> src/main.rs:15:13
   |
15 |             shorter.push(bit_sign); // Error here
   |             ^^^^^^^ cannot borrow as mutable

尽管我用 mut 说明符声明了它。

最佳答案

shorter 的类型是一个引用,更准确地说是一个&Vec<bool> , 这意味着它指的是 Vec<bool>不允许对其进行突变1

将变量声明为 mut shorter只做 shorter variable 可变的,允许你例如使用 shorter = ...分配以使其引用不同的 Vec<bool> .无论变量的可变性如何,类型为 &Vec<bool> 的共享引用不允许改变它引用的对象。

您需要做的是创建一个类型为 &mut Vec<bool> 的可变引用, 使用 &mut bit_vec0&mut bit_vec1 .此更改使代码可以编译,此时 shorter不再需要 mut .

最后,这与问题无关,match_lengths接受 bit_vec0bit_vec1按值,修改它们,然后返回它们。虽然这确实有效,但接受可变引用更为惯用。这种方法对调用者来说更符合人体工程学,并且更清楚地表明该函数实际上并不“返回”任何东西,它实际上修改了现有对象。

经过这些修改,函数看起来像这样:

fn match_lengths(bit_vec0: &mut Vec<bool>, bit_vec1: &mut Vec<bool>) {
    let (shorter, longer) = if bit_vec0.len() < bit_vec1.len() {
        (bit_vec0, bit_vec1)
    } else {
        (bit_vec1, bit_vec0)
    };
    let bit_sign = match shorter.last() {
        Some(content) => *content,
        None => false,
    };
    for _ in shorter.len()..longer.len() {
        shorter.push(bit_sign);
    }
}

1 这听起来很像 C++ 的 const , 但 Rust 中的保证比 const 的保证还要强:不仅共享(非 mut)引用不允许改变它所指的对象,其他任何人也不允许! Rust 的编译器和运行时阻止创建 mut对该对象的任何共享引用存在时对该对象的引用。

关于rust - 即使声明为可变的,变量也被认为是不可变的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47242768/

相关文章:

python - 列表列表更改意外地反射(reflect)在子列表中

rust - 当我需要引用自身时如何设计结构

graph - "cannot borrow ` graph ` as immutable because it is also borrowed as mutable."我怎样才能让 Rust 知道我已经完成了那个可变借用?

Python 作用域可变与不可变

c# - 更新对不可变对象(immutable对象)的引用的首选方法是什么?

scala - 将案例类用于可变状态是否(真的)不好?

enums - 如何根据其判别式创建无字段枚举变体?

rust - 有条件地迭代几个可能的迭代器之一

reference - 如何通过引用使用包含可变引用的不可变选项?

javascript - 可以从闭包访问可变变量。我怎样才能解决这个问题?