如何从 Rc<RefCell<A>> 获取 &A 引用?
How can I obtain an &A reference from a Rc<RefCell<A>>?
我有一个设计问题,我想用安全的 Rust 解决,但我找不到可行的解决方案。我不能使用 RefCell
,因为您无法获得对数据的 & 引用,只能使用 Ref
/ RefMut
.
这是一个simplified example with irrelevant fields / methods removed
use std::cell::RefCell;
use std::rc::Rc;
struct LibraryStruct {}
impl LibraryStruct {
fn function(&self, _a: &TraitFromLibrary) {}
}
trait TraitFromLibrary {
fn trait_function(&self, library_struct: LibraryStruct);
}
// I don't want to copy this, bad performance
struct A {
// fields...
}
impl TraitFromLibrary for A {
fn trait_function(&self, library_struct: LibraryStruct) {
// custom A stuff
}
}
// B manipulates A's in data
struct B {
data: Vec<A>,
}
struct C {
// This type doesn't have to be & for solution. C just needs immutable access
a: Rc<RefCell<A>>,
}
impl<'a> TraitFromLibrary for C {
fn trait_function(&self, library_struct: LibraryStruct) {
// custom C stuff
// Takes generic reference &, this is why Ref / RefCell doesn't work
library_struct.function(&self.a.borrow());
}
}
// B and C's constructed in Container and lifetime matches Container
// Container manipulates fields b and c
struct Container {
b: B,
c: Vec<C>,
}
fn main() {}
我可以用 Rc<RefCell<A>>
解决这个问题,但我被限制在需要 &A
的库中。
这会产生错误:
error[E0277]: the trait bound `std::cell::Ref<'_, A>: TraitFromLibrary` is not satisfied
--> src/main.rs:33:33
|
33 | library_struct.function(&self.a.borrow());
| ^^^^^^^^^^^^^^^^ the trait `TraitFromLibrary` is not implemented for `std::cell::Ref<'_, A>`
|
= note: required for the cast to the object type `TraitFromLibrary`
如果一个函数有一个类型为 &A
的参数,那么您可以使用对任何取消引用 A
的类型的引用来调用它,其中包括 &Ref<A>
]. Deref
特征捕获了一种类型对另一种类型的取消引用的概念。这也是为什么接受 &str
的函数可以用 &String
(String: Deref<Target = str>
) 调用的原因。
因此,如果您将 a
保留为 Rc<RefCell<A>>
,您可以像这样轻松修复代码:
library_struct.function(&*self.a.borrow());
请注意,这会取消引用 A
然后 重新借用 它以便可以将其强制转换为特征对象。
我有一个设计问题,我想用安全的 Rust 解决,但我找不到可行的解决方案。我不能使用 RefCell
,因为您无法获得对数据的 & 引用,只能使用 Ref
/ RefMut
.
这是一个simplified example with irrelevant fields / methods removed
use std::cell::RefCell;
use std::rc::Rc;
struct LibraryStruct {}
impl LibraryStruct {
fn function(&self, _a: &TraitFromLibrary) {}
}
trait TraitFromLibrary {
fn trait_function(&self, library_struct: LibraryStruct);
}
// I don't want to copy this, bad performance
struct A {
// fields...
}
impl TraitFromLibrary for A {
fn trait_function(&self, library_struct: LibraryStruct) {
// custom A stuff
}
}
// B manipulates A's in data
struct B {
data: Vec<A>,
}
struct C {
// This type doesn't have to be & for solution. C just needs immutable access
a: Rc<RefCell<A>>,
}
impl<'a> TraitFromLibrary for C {
fn trait_function(&self, library_struct: LibraryStruct) {
// custom C stuff
// Takes generic reference &, this is why Ref / RefCell doesn't work
library_struct.function(&self.a.borrow());
}
}
// B and C's constructed in Container and lifetime matches Container
// Container manipulates fields b and c
struct Container {
b: B,
c: Vec<C>,
}
fn main() {}
我可以用 Rc<RefCell<A>>
解决这个问题,但我被限制在需要 &A
的库中。
这会产生错误:
error[E0277]: the trait bound `std::cell::Ref<'_, A>: TraitFromLibrary` is not satisfied
--> src/main.rs:33:33
|
33 | library_struct.function(&self.a.borrow());
| ^^^^^^^^^^^^^^^^ the trait `TraitFromLibrary` is not implemented for `std::cell::Ref<'_, A>`
|
= note: required for the cast to the object type `TraitFromLibrary`
如果一个函数有一个类型为 &A
的参数,那么您可以使用对任何取消引用 A
的类型的引用来调用它,其中包括 &Ref<A>
]. Deref
特征捕获了一种类型对另一种类型的取消引用的概念。这也是为什么接受 &str
的函数可以用 &String
(String: Deref<Target = str>
) 调用的原因。
因此,如果您将 a
保留为 Rc<RefCell<A>>
,您可以像这样轻松修复代码:
library_struct.function(&*self.a.borrow());
请注意,这会取消引用 A
然后 重新借用 它以便可以将其强制转换为特征对象。