Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

Here is a 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() {}

I would be able to solve this with Rc<RefCell<A>> but I am being restricted from the library requiring &A.

This produces the error:

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`
like image 789
Jake Avatar asked Sep 01 '18 00:09

Jake


People also ask

How long does it take for IPA to be approved?

It takes around 8 weeks to process the application. It may take longer if additional information is required. If you receive an email from MOM requesting for more documents, you can submit them using this online form. You can check the application status online.

How do I issue's pass?

Log in to myMOM Portal and provide the required information and documents. Pay the $100 fee for each pass issued using GIRO, VISA or MasterCard. Once the pass is issued, the candidate and you will both receive the notification letter by email.

Is Ein the same as tax ID?

An Employer Identification Number (EIN) is also known as a federal tax identification number, and is used to identify a business entity. It is also used by estates and trusts which have income which is required to be reported on Form 1041, U.S. Income Tax Return for Estates and Trusts.


1 Answers

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>).

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());

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

like image 93
Peter Hall Avatar answered Oct 16 '22 17:10

Peter Hall