具有对其他结构的不可变引用的struct

时间:2015-07-20 10:46:57

标签: rust

首先,我想为这个带有非特定标题的noob问题道歉,我对Rust很新。

无论如何,这里有一些(工作)代码:

struct A {
    data: i32
}

struct B<'s> {
    a: &'s A
}

impl<'s> B<'s> {
    fn new(reference: &'s A) -> B<'s> {
        B {
            a: reference
        }
    }
}

fn main() {
    let a1 = A{data: 0};
    let b1 = B::new(&a1);
    let b2 = B::new(&a1);
}

结构A包含一些数据,结构B包含对A的不可变引用。在main方法中,创建了几个B对象,引用了单个A对象。

现在我只想改变一件事:在B :: new()方法中,我想在将它作为B的不可变成员使用之前修改'reference'的数据。我试过这样:

struct A {
    data: i32
}

struct B<'s> {
    a: &'s A
}

impl<'s> B<'s> {
    fn new(reference: &'s mut A) -> B<'s> {

        // Modify data
        reference.data += 1;

        B {
            a: reference
        }
    }
}

fn main() {
    let mut a1 = A{data: 0};
    let b1 = B::new(&mut a1);
    let b2 = B::new(&mut a1);
}

但是编译器不会让我,错误:不能一次多次将a1借用为可变的。一旦new()完成,为什么不可变借用?什么是实现我正在尝试的正确方法?

2 个答案:

答案 0 :(得分:1)

正如@AndreaP所说,问题是因为你的生命相同的参考。

通常,只需分割您的功能(一个&和一个&mut),您就可以解决这些问题。

如果你真的需要这种模式,那么我认为你要找的是Cell / RefCellhttp://doc.rust-lang.org/std/cell/index.html

编辑:感谢@Ker评论,我更新了代码,因此B确实包含对A的引用,而不是其副本。旧代码完全错了。

use std::cell::{Cell};

#[derive(Debug)]
struct A {
    data: Cell<i32>
}

#[derive(Debug)]
struct B<'a> {
    a: &'a A
}

impl<'a> B<'a> {
    fn new(reference: &'a A) -> B<'a> {
        // Modify data
        reference.data.set(reference.data.get() + 1);
        B {
            a: reference
        }
    }
}

fn main() {
    let a1 = A{data: Cell::new(0)};
    let b1 = B::new(&a1);
    let b2 = B::new(&a1);
    println!("{}", a1.data.get());
    println!("{:?}", b1);
    println!("{:?}", b2);
}

答案 1 :(得分:0)

借用尚未完成,因为您在b1中保持该引用存活。因此,当您尝试对b2执行相同操作时,借用仍然存在。

也许你只想要这个:

fn main() {
    let mut a1 = A{data: 0};
    let mut a2 = A{data: 0};
    let b1 = B::new(&mut a1);
    let b2 = B::new(&mut a2);
}