Rust 借用对结构中属性的引用
如果借用对结构字段的引用,则整个结构被视为借用。我已经成功地把我想做的事情孤立出来并举例说明。我只想获得对Rust 借用对结构中属性的引用,rust,Rust,如果借用对结构字段的引用,则整个结构被视为借用。我已经成功地把我想做的事情孤立出来并举例说明。我只想获得对B中某个字段的“只读”引用,以获取一些数据,然后修改B的另一个字段。有没有一种惯用的生锈方法 struct A { i: i32, } struct B { j: i32, a: Box<A>, } impl B { fn get<'a>(&'a mut self) -> &'a A { &am
B
中某个字段的“只读”引用,以获取一些数据,然后修改B
的另一个字段。有没有一种惯用的生锈方法
struct A {
i: i32,
}
struct B {
j: i32,
a: Box<A>,
}
impl B {
fn get<'a>(&'a mut self) -> &'a A {
&*self.a
}
fn set(&mut self, j: i32) {
self.j = j
}
}
fn foo(a: &A) -> i32 {
a.i + 1
}
fn main() {
let a = Box::new(A { i: 47 });
let mut b = B { a: a, j: 1 };
let a_ref = b.get();
b.set(foo(a_ref));
}
这是语言的一个特点。从编译器的角度来看,当通过
get()
借用a
时,它无法知道调用set()
函数是安全的
您的get()
函数可变地借用b
,并返回一个引用,因此b
将保持借用状态,直到该引用超出范围
您有几种处理方法:
B方法中移动需要访问这两个属性的代码
fn main() {
let a = Box::new(A { i: 47 });
let mut b = B { a: a, j: 1 };
let newval = {
let a_ref = b.get();
foo(a_ref)
};
b.set(newval);
}
B方法中移动需要访问这两个属性的代码
第一次通过时可能是这样的:
impl B {
fn do_thing(&mut self) {
self.j = self.a.foo()
}
}
但是,这会对调用foo
进行硬编码。您也可以接受一个闭包,以使其更灵活:
impl B {
fn update_j_with_a<F>(&mut self, f: F)
where
F: FnOnce(&mut A) -> i32,
{
self.j = f(&mut self.a)
}
}
// ...
b.update_j_with_a(|a| a.foo())
可以换成
struct A {
description: String,
info: Info,
}
struct Info {
name: String,
age: u8,
money: i32,
}
impl A {
fn update_description(&mut self) {
let description = &mut self.description;
*description = self.info.build_description()
}
}
impl Info {
fn build_description(&self) -> String {
format!(
"{} is {} years old and has {} money",
self.name,
self.age,
self.money
)
}
}
fn main() {}
您可以将这两个步骤结合起来(我认为这是更好的做法),然后将该方法移到内部结构上。注意,在中,在设置新值之前计算新值。
,额外的大括号会导致b.get
中的可变引用的作用域在我们尝试设置值之前过期-这很好地回到了点“b
将保持借用状态,直到该引用超出作用域”。
struct A {
description: String,
info: Info,
}
struct Info {
name: String,
age: u8,
money: i32,
}
impl A {
fn update_description(&mut self) {
let description = &mut self.description;
*description = self.info.build_description()
}
}
impl Info {
fn build_description(&self) -> String {
format!(
"{} is {} years old and has {} money",
self.name,
self.age,
self.money
)
}
}
fn main() {}