Reputation: 443
In the example we assume that we have two codes that has their perimeter and tested individually.
The code 1 return the type Option<Rc<RefCell<T>>>
and code 2 that have to consume &T
.
I have an issues with the following example playground.
use std::cell::RefCell;
use std::rc::Rc;
// Code 2
fn action(data_1: Option<&i32>, data_2: Option<&i32>) {
println!("data_1:{:?}, data_2:{:?}", data_1, data_2);
}
fn main() {
// Code 1
let data_1 = Some(Rc::new(RefCell::new(2)));
let data_2 = Some(Rc::new(RefCell::new(5)));
let ref_data_1 = data_1.as_ref().map(|r| r.borrow());
let ref_data_2 = data_2.as_ref().map(|r| r.borrow());
action(ref_data_1, ref_data_2); // Error: mismatched types
}
The example fail because of mismatch types between Ref<T>
is found and &T
is expected.
My only way that I have founded is to change Option<&i32>
to Option<Ref<i32>>
but that break the interface of code 2.
Upvotes: 0
Views: 313
Reputation: 58725
You can change the action
function to accept either Option<&i32>
or Option<Ref<i32>>
by using a generic argument with a Deref<Target = i32>
bound, which both of those types satisfy:
use std::ops::Deref;
fn action<T>(data_1: Option<T>, data_2: Option<T>)
where
T: Deref<Target = i32>,
{
println!("data_1:{:?}, data_2:{:?}", data_1.as_deref(), data_2.as_deref());
}
If you can't or don't want to change the signature of action
, then you can call as_deref()
on the arguments when you pass them in:
action(ref_data_1.as_deref(), ref_data_2.as_deref());
Upvotes: 4