我有一个设计问题,希望用安全的Rust解决,但我还没有找到可行的解决方案。我不能使用RefCell
,因为你只能得到Ref
/RefMut
而不是数据的&引用。
这里是一个简化的示例,已删除不相关的字段/方法
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
。结构体B和C同时存在于容器中,这会导致可变性问题,因为在C中存在一个不可变引用,而B有时需要可变性。 - JakeC
的a
是一个RefCell
,但这在库函数中行不通? - Peter HallRc<RefCell<A>>
,然后将其作为library_struct.function(&self.a.borrow())
传递给库函数。 - Peter HallRef
都实现了Deref
接口。如果一个函数接受一个&
引用,则您可以传递任何实现Deref
的类型的引用,例如这个示例。 - Peter Hall