[英]How can I implement Deref for a struct that holds an Rc<Refcell<Trait>>?
My goal is to delegate method calls against my struct to a Trait's methods, where the Trait object is inside an Rc
of RefCell
. 我的目标是将针对我的结构的方法调用委托给Trait的方法,其中Trait对象位于RefCell
的Rc
中。
I tried to follow the advice from this question: How can I obtain an &A reference from a Rc<RefCell<A>>? 我试图遵循以下问题的建议: 如何从Rc <RefCell <A >>获取&A参考?
I get a compile error. 我收到一个编译错误。
use std::rc::Rc;
use std::cell::RefCell;
use std::fmt::*;
use std::ops::Deref;
pub struct ShyObject {
pub association: Rc<RefCell<dyn Display>>
}
impl Deref for ShyObject {
type Target = dyn Display;
fn deref<'a>(&'a self) -> &(dyn Display + 'static) {
&*self.association.borrow()
}
}
fn main() {}
Here is the error: 这是错误:
error[E0515]: cannot return value referencing temporary value
--> src/main.rs:13:9
|
13 | &*self.association.borrow()
| ^^-------------------------
| | |
| | temporary value created here
| returns a value referencing data owned by the current function
My example uses Display
as the trait; 我的示例使用Display
作为特征。 in reality I have a Trait with a dozen methods. 实际上,我有很多方法的特质。 I am trying to avoid the boilerplate of having to implement all those methods and just burrow down to the Trait object in each call. 我试图避免必须实现所有这些方法的样板,而只是在每个调用中探究Trait对象。
You can't. 你不能 RefCell::borrow
returns a Ref<T>
, not a &T
. RefCell::borrow
返回Ref<T>
,而不是&T
。 If you try to do this in a method then you will need to first borrow the Ref<T>
but it will go out of scope. 如果尝试使用方法来执行此操作,则需要首先借用Ref<T>
但它会超出范围。
Instead of implementing Deref
, you could have a method that returns something that does: 除了实现Deref
,您还可以使用一个方法返回执行Deref
的方法:
impl ShyObject {
fn as_deref(&self) -> impl Deref<Target = dyn Display> {
self.association.borrow()
}
}
Otherwise, since you only want to expose the Display
implementation of the inner data anyway, you can workaround it by actually dereferencing a different type which delegates: 否则,由于无论如何您只想公开内部数据的Display
实现,因此可以通过实际取消引用委托的其他类型来解决此问题:
pub struct ShyObject {
association: Assocation<dyn Display>,
}
struct Assocation<T: ?Sized>(Rc<RefCell<T>>);
impl<T: Display + ?Sized> fmt::Display for Assocation<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0.borrow())
}
}
impl Deref for ShyObject {
type Target = dyn Display + 'static;
fn deref(&self) -> &Self::Target {
&self.association
}
}
You cannot do that. 你不能这样做。 borrow
creates a new struct that allows RefCell
to track the borrow. borrow
创建一个新的结构 ,该结构允许RefCell
跟踪借位。 You're then not allowed to return a borrow to this Ref
, because it is a local variable. 然后,您将不允许向此Ref
返回借用,因为它是局部变量。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.