【问题标题】:Adding to vector after indexing from it从它索引后添加到向量
【发布时间】:2021-07-27 23:40:16
【问题描述】:

我很好奇这里的这个例子https://doc.rust-lang.org/book/ch08-01-vectors.html

$ cargo run
   Compiling collections v0.1.0 (file:///projects/collections)
error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable
 --> src/main.rs:6:5
  |
4 |     let first = &v[0];
  |                  - immutable borrow occurs here
5 | 
6 |     v.push(6);
  |     ^^^^^^^^^ mutable borrow occurs here
7 | 
8 |     println!("The first element is: {}", first);
  |                                          ----- immutable borrow later used here

error: aborting due to previous error

For more information about this error, try `rustc --explain E0502`.
error: could not compile `collections`

To learn more, run the command again with --verbose.

在高层次上,对v 中的项目的引用与对v 本身的引用有何相同之处。从语法上讲,这是如何执行的? 如何简单地实现带有示例类型的东西来举例说明这一点?到目前为止,我所能找到的只是所有权阻止了这一点,但我找不到任何解释它的东西。

感谢任何帮助!

【问题讨论】:

    标签: rust


    【解决方案1】:

    如果需要调整向量的大小以容纳额外的项目,它必须分配新的内存并将所有现有的项目移动到新的分配中。这会破坏出色的参考,这就是不允许的原因。其他形式的突变可能同样会破坏引用 - 例如删除项目可能会删除被引用的项目或导致其在向量内移动。

    这是通过生命周期和引用在 Rust 中的工作方式强制执行的。 Vecs 实现Index trait 以提供[] 运算符,该运算符具有fn index(&self, index: Idx) -> &Self::Output 的方法签名。请注意 self 是如何被不可变引用 (&) 获取的,并且该函数还返回一个不可变引用。由于没有为这些引用明确指定生命周期,因此编译器推断它们是链接的 - 即,返回的引用仅在对容器本身的引用有效时才有效。

    接下来,您尝试使用push 对向量进行变异。这有签名fn push(&mut self, value: T)。请注意,此函数通过 mutable 引用 (&mut) 获取 self,这要求没有其他对向量的引用。由于编译器在上一步中发现对向量进行索引会返回与向量本身相关联的引用,因此它不允许我们调用push

    您可以使用如下代码非常轻松地创建一个类似的示例:

    struct MyStruct {
        a: i32
    }
    
    impl MyStruct {
        fn get_a(&self) -> &i32 {
            &self.a
        }
        
        fn set_a(&mut self, value: i32) {
            self.a = value;
        }
    }
    
    fn main() {
        let mut thing = MyStruct { a: 5 };
        let reference = thing.get_a();
        thing.set_a(10); // error! thing is already borrowed due to get_a()
        println!("Value: {}", reference);
    }
    

    Rust 书在几个地方涉及这些主题。我建议通读References and BorrowsValidating references with lifetimes

    【讨论】:

    • 我希望我能对这个答案投两次赞成票,你!!我缺少的重要部分是 &someInstance.someField 也确实在借用实例,而不仅仅是字段
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多