【发布时间】:2018-09-01 00:44:19
【问题描述】:
我有一个设计问题,我想用安全的 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`
【问题讨论】:
-
我试图模糊 C 的字段类型,因为它不能是
&'a A。结构 B 和 C 在 Container 中同时存在,并且存在可变性问题,因为 C 中存在不可变引用,而 B 有时需要可变性。 -
好的,理想情况下,您希望
C的a成为RefCell,但这不适用于库函数? -
是的,因为您不能仅从 RefCell 获得 &A Ref / RefMut
-
我刚刚做了一些更改,我认为这可以传达您的意思。我认为答案是只需
Rc<RefCell<A>>,然后将其传递给库函数library_struct.function(&self.a.borrow()); -
这是可行的,因为
Ref都实现了Deref。如果函数接受&-reference,那么您可以将引用传递给实现Deref的任何类型,如this example。
标签: reference rust smart-pointers borrowing