如何从 Rc<RefCell<A> 获得 &A 引用? [英] How can I obtain an &A reference from a Rc<RefCell<A>>?

查看:37
本文介绍了如何从 Rc<RefCell<A> 获得 &A 引用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些设计问题,我想用安全的 Rust 来解决,但我一直无法找到可行的解决方案.我不能使用 RefCell 因为你不能得到 &引用数据,只有Ref/RefMut.

I have design issue that I would like solve with safe Rust that I haven't been able to find a viable solution. I can't use a RefCell because you can't get a & reference to the data, only 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> 解决这个问题,但我被限制在需要 &A 的库中.

I would be able to solve this with Rc<RefCell<A>> but I am being restricted from the library requiring &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 之类的内容.Deref 捕获了一种类型取消引用另一种类型的概念 特性.这也是为什么接受 &str 的函数可以用 &String (String: Deref).

If a function has an argument which is a of type &A, then you can call it with a reference to any type that dereferences to A, which includes things like &Ref<A>. The concept of one type dereferencing to another is captured by the Deref trait. This is also the reason why a function that accepts &str can be called with &String (String: Deref<Target = str>).

因此,如果您将 a 保留为 Rc>,您可以像这样轻松修复代码:

So, if you keep a as a Rc<RefCell<A>>, you can fix your code quite easily like this:

library_struct.function(&*self.a.borrow());

请注意,这会取消对 A 的引用,然后 重新借用,以便将其强制转换为 trait 对象.

Note that this dereferences A and then reborrows it so that it can be coerced to a trait object.

这篇关于如何从 Rc&lt;RefCell&lt;A&gt; 获得 &amp;A 引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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