I have a struct that refers to a value (because is it ?Sized or very large). Of course, this value must live with the structure.
However, the structure should not limit the user to how to do this. Regardless of whether the user transfers the value to Box or Rc or makes it 'static , the value simply needs to be saved with the structure. Using the named lifetimes would be difficult because the link will be moved and can survive our struct . I am looking for a generic pointer type (if it exists / can exist).
How can a structure ensure that the reference value works as long as the structure exists, without specifying how?
Example ( is.gd/Is9Av6 ):
type CallBack = Fn(f32) -> f32; struct Caller { call_back: Box<CallBack>, } impl Caller { fn new(call_back: Box<CallBack>) -> Caller { Caller {call_back: call_back} } fn call(&self, x: f32) -> f32 { (self.call_back)(x) } } let caller = { // func goes out of scope let func = |x| 2.0 * x; Caller {call_back: Box::new(func)} }; // func survives because it is referenced through a `Box` in `caller` let y = caller.call(1.0); assert_eq!(y, 2.0);
Compiles, all is well. But if we don’t want to use Box as a pointer to our function (you can call Box pointer, right?), But something else, such as Rc , this will not be possible, since Caller restricts the pointer to Box .
let caller = { // function is used by `Caller` and `main()` => shared resource // solution: `Rc` let func = Rc::new(|x| 2.0 * x); let caller = Caller {call_back: func.clone()}; // ERROR Rc != Box // we also want to use func now let y = func(3.0); caller }; // func survives because it is referenced through a `Box` in `caller` let y = caller.call(1.0); assert_eq!(y, 2.0);
( is.gd/qUkAvZ )
Possible Solution: Deref ? ( http://is.gd/mmY6QC )
use std::rc::Rc; use std::ops::Deref; type CallBack = Fn(f32) -> f32; struct Caller<T> where T: Deref<Target = Box<CallBack>> { call_back: T, } impl<T> Caller<T> where T: Deref<Target = Box<CallBack>> { fn new(call_back: T) -> Caller<T> { Caller {call_back: call_back} } fn call(&self, x: f32) -> f32 { (*self.call_back)(x) } } fn main() { let caller = { // function is used by `Caller` and `main()` => shared resource // solution: `Rc` let func_obj = Box::new(|x: f32| 2.0 * x) as Box<CallBack>; let func = Rc::new(func_obj); let caller = Caller::new(func.clone()); // we also want to use func now let y = func(3.0); caller }; // func survives because it is referenced through a `Box` in `caller` let y = caller.call(1.0); assert_eq!(y, 2.0); }
Is this a way to go with rust? Using Deref ? It works as a minimum.
Am I missing something obvious?
This question did not solve my problem, since the value is practically not applicable as T