如何在Rust中借用可变指针?

3

我有一个函数返回了一个Result<&'a ~Foo, BarErr>,可以通过以下方式进行访问:

match x.borrow() {
  Ok(ref foo) => println!("Found {}", foo.value),
  Err(Nope) => println!("Bleh")
}

然而,我现在发现自己面临一个更加复杂的情况,我希望借用一个可变引用,这样我就可以在它上面调用一个函数:
match x.borrow() {
  Ok(ref foo) => { foo.inc(); trace!("Found {}", foo.value); },
  Err(Nope) => trace!("Bleh")
}

我尝试了几种方法来确定在哪里需要添加“mut”,例如mut ref foo,ref mut foo,-> mut Result<...>,-> Result,但我似乎无法弄清所需的语法。

我一直得到:

error: cannot borrow immutable dereference of `~`-pointer `***foo` as mutable

它应该是什么?

完整示例代码:

macro_rules! trace(
  ($($arg:tt)*) => (
    { let x = ::std::io::stdout().write_line(format_args!(::std::fmt::format, $($arg)*)); println!("{}", x); }
  );
)

#[deriving(Show)]
struct Foo {
  value: int
}

impl Foo {
  fn inc(&mut self) {
    self.value += 1;
  }
}

#[deriving(Show)]
struct Bar {
  data: Option<~Foo>
}

#[deriving(Show)]
enum BarErr {
  Nope
}

impl Bar {
  fn borrow<'a>(&'a mut self) -> Result<&'a ~Foo, BarErr> {
    match self.data {
      Some(ref e) => return Ok(e),
      None => return Err(Nope)
    }
  }
}

#[test]
fn test_create_indirect() {
  let y = ~Foo { value: 10 };
  let mut x = Bar { data: Some(y) };
  let mut x2 = Bar { data: None };
  {
    match x.borrow() {
      Ok(ref mut foo) => { foo.inc(); trace!("Found {}", foo.value); },
      Err(Nope) => trace!("Bleh")
    }
  }
  {
    let z = x2.borrow();
    trace!("Z: {}", z);
  }
}
1个回答

4
问题在于引用没有拥有数据,因此它们的可变性是继承而来的。你无法将 &'a 转换为 &'a mut,因为该引用下的数据是不可变的。
要实现你想要的效果,你必须返回 Result<&'a mut ~Foo, BarErr>
impl Bar {
  fn borrow<'a>(&'a mut self) -> Result<&'a mut ~Foo, BarErr> {
    match self.data {
      Some(ref mut e) => return Ok(e),
      None => return Err(Nope)
    }
  }
}

#[test]
fn test_create_indirect() {
  let y = ~Foo { value: 10 };
  let mut x = Bar { data: Some(y) };
  let mut x2 = Bar { data: None };
  {
    match x.borrow() {
      Ok(foo) => { foo.inc(); trace!("Found {:?}", foo.value); },
      Err(Nope) => trace!("Bleh")
    }
  }
  {
    let z = x2.borrow();
    trace!("Z: {:?}", z);
  }
}

请注意,在使用站点上,我将x.borrow()Ok(foo)相匹配,而不是Ok(ref mut foo)。这没问题,因为foo本身是&mut,所以你可以通过它访问&mut self方法。

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