2015-07-20 36 views
0

首先,我想为这个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.在main方法几个B-对象是一个结构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()完成后,可变的借款不会结束?什么是正确的方式来实现我想要的?

回答

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

谢谢!你是完全正确的,我相应地修改了代码。 – 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); 
} 
+0

感谢您的回答。不幸的是我需要在我的应用程序中正好有一个A对象被几个B对象引用。 – stfnp