带有对其他结构体不可变引用的结构体

3

首先,我要为这个没有具体标题的初学者问题道歉,我对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,还有一个包含对A不可变引用的结构体B。在主方法中,创建了几个具有引用相同A对象的B对象。

现在我只想改变一件事:在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个回答

4
正如@AndreaP所说,问题是由于您引用了相同生命周期的变量。通常情况下,您可以通过将函数分成一个&和一个&mut来解决这些问题。
如果您确实需要这种模式,则认为您要查找的是Cell/RefCell:http://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);
}

谢谢!你说得完全正确,我已经相应地修改了代码。 - tafia

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);
}

谢谢您的回答。不幸的是,在我的应用程序中,我需要几个B对象引用一个A对象。 - Stefan Pfeifer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接