借用对结构中属性的引用 [英] Borrowing references to attributes in a struct

查看:39
本文介绍了借用对结构中属性的引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

似乎如果你借用一个结构域的引用,整个结构体就被认为是借用的.我已经设法将我想做的事情隔离开来并举例说明.我只想获得对 B 中某个字段的只读"引用以获取一些数据,然后修改 B 的另一个字段.有没有惯用的 Rust 方法来做到这一点?

It seems that if you borrow a reference to a struct field, the whole struct is considered borrowed. I've managed to isolate and example of what I want to do. I just want to get a "read-only" reference to a field in B to obtain some data and then modify another field of B. Is there a idiomatic Rust way to do this?

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

error[E0499]: cannot borrow `b` as mutable more than once at a time
  --> src/main.rs:27:5
   |
26 |     let a_ref = b.get();
   |                 - first mutable borrow occurs here
27 |     b.set(foo(a_ref));
   |     ^ second mutable borrow occurs here
28 | }
   | - first borrow ends here

推荐答案

这是语言的一个特性.从编译器的角度来看,它无法知道调用 set() 函数是安全的,而 a 是通过 get() 借用的.

It's a feature of the language. From the compiler point of view, there is no way for it to know that it's safe to call your set() function while a is borrowed via get().

您的 get() 函数可变地借用 b,并返回一个引用,因此 b 将保持借用状态,直到此引用超出范围.

Your get() function borrows b mutably, and returns a reference, thus b will remain borrowed until this reference goes out of scope.

您有多种处理方法:

  1. 将你的两个字段分成两个不同的结构

  1. Separate your two fields into two different structs

将需要访问两个属性的代码移动到B

Move the code which needs to access both attribute inside a method of B

公开你的属性,这样你就可以直接获得对它们的引用

Make your attributes public, you will thus be able to directly get references to them

在设置之前计算新值,像这样:

Compute the new value before setting it, like this:

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

这篇关于借用对结构中属性的引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆