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

防止不能借用'*自'作为不可变的,因为它也借用作为可变时访问结构中的不相交字段?

周楷
2023-03-14

之前的问题,这不是重复的:

  • 不能借用'*自'作为可变的,因为它也是借用作为不可变的
    • 这个问题是不相关的b/c答案最终是Rust编译器有一个bug,我很确定不是这里的情况。

    我有以下结构:

    struct Foo {
        data: Vec<Bar>,
        a: usize,
    }
    
    struct Bar {
        b: usize
    }
    

    impl Foo中,我有以下方法:

    fn example(&mut self, c: usize) {
        let baz = &mut self.data[c];
        let z = self.calc(c);
        baz.b = 42 + z;
    }
    
    fn calc(&self, x: usize) -> usize {
        self.a * x
    }
    

    当然,Rust编译器会抛出一个错误,大致是这样说的:“当您创建baz时会发生可变借用,然后当您调用self.calc时会执行不可变借用,最后当您分配给baz.a时会使用可变借用。”。

    但是,我访问结构上的不相交字段,因为calc从不读取通过baz写入的数据。

    有办法通知Rust编译器吗?

共有2个答案

柯乐童
2023-03-14

我最终做了:

fn example(&mut self, c: usize) {
    let baz = &self.data[c];
    // some stuff that requires reading `baz`
    let z = self.calc(c);
    let baz = &mut self.data[c];
    baz.b = 42 + z;
}

fn calc(&self, x: usize) -> usize {
    self.a * x
}
孟祯
2023-03-14

问题是Foo::calc的签名,需要

calc从不读取写入到baz中的数据这一事实是无关紧要的。在Rust中,对函数或方法的所有了解都暴露在签名中;编译器从不查看函数以确定它是否是特殊情况。

通过不要求calc获取

impl Foo {
    fn example(&mut self, c: usize) {
        let baz = &mut self.data[c];
        // This avoids borrowing `self` in its entirety...
        let z = Self::calc(self.a, c);
        baz.b = 42 + z;
    }

    fn calc(a: usize, x: usize) -> usize {
        a * x
    }
}

 类似资料:
  • 可变数据可以使用 &mut T 进行可变借用。这叫做可变引用(mutable reference),并赋予了借用者读/写访问能力。相反,&T 通过不可变引用(immutable reference)来借用数据,借用者可以读数据而不能更改数据: #[allow(dead_code)] #[derive(Clone, Copy)] struct Book { // `&'static str`

  • 本文向大家介绍Python为何不能用可变对象作为默认参数的值,包括了Python为何不能用可变对象作为默认参数的值的使用技巧和注意事项,需要的朋友参考一下 先来看一道题目: 我们似乎发现了一个Bug,每次用相同的方式调用函数 func() 时,返回结果竟然不一样,而且每次返回的列表在不断地变长。 从上面可以看出,函数的返回值其实是同一个列表对象,因为他们的id值是一样的,只不过是列表中的元素在变化

  • 下面是一个不可变类的示例: 下面是类的实现: 当我创建的实例时,我正在的构造函数中对进行深度复制,但是我能够通过更新的值,这种方法破坏了my类的不变性。我在这里做错了什么?

  • 问题内容: 我想让一个函数交换2个变量!但是对于新的Swift,我不能使用’var’…。 问题答案: 文字不能作为inout参数传递,因为它们本质上是不可变的。 请改用两个变量: 此外,对于最后的Swift 3快照之一,应将inout放置在类型附近,您的函数原型将变为:

  • 我正在尝试在 Kotlin 中生成一个单例,并且遇到了问题,因为我无法。 这似乎是制作单例的一种非常标准的方法。为什么它不让我,我该如何解决它?

  • 我知道借阅检查器不允许多个可变借阅。例如,下面的代码无效: 但是,如果第一次借款因超出范围而被放弃,第二次借款是有效的: 由于非词汇生存期(NLL),第一次借用甚至不必超出范围-借用检查器只要求不再使用它。因此,以下代码在2018年有效: 但我不明白为什么下面的代码无效: 编译错误信息: 从错误消息中,我认为NLL可能还不支持这种情况。所以,我提前删除了: (铁锈操场) 但我得到了一个更令人困惑的