繁体   English   中英

如何从 Rc 获得 &amp;A 参考<RefCell<A> &gt;?

[英]How can I obtain an &A reference from a Rc<RefCell<A>>?

我有设计问题,我想用安全的 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的任何类型的引用来调用它,其中包括&Ref<A>之类的东西。 Deref特征捕获了一种类型对另一种类型的解引用的概念。 这也是接受&str的函数可以用&String ( String: Deref<Target = str> ) 调用的原因。

因此,如果您将a保留为Rc<RefCell<A>> ,您可以很容易地修复您的代码,如下所示:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM