rust - Struct that owns some data and a reference to the data -
this question has answer here:
construction of object allocates data needed lifetime of object, creates object needs keep references data:
pub fn new() -> obj { let data = compute(); obj { original: data, processed: anotherobj { reference: &data } } } is possible express in rust's terms?
here i'd obj, anotherobj , data have same lifetime, , of course outlive new() call.
a raw design of structs based on requirements might this:
struct anotherobj<'a> { original: &'a vec<i8>, // let's agree on vec<i8> "data" type. } struct obj<'a> { original: vec<i8>, // <-------------------+ processed: anotherobj<'a>, // should point here --+ } however it's tricky working (personally, wasn't able to) because want 'a in anotherobj<'a> lifetime of original. must supply lifetime obj<'a> , have specify obj<'tbc> 'tbc lifetime of obj created.
i suggest following alternatives:
1. make anotherobj own original
why not? obj own anotherobj, can still have access original nested child:
pub struct anotherobj { original: vec<i8>, } pub struct obj { processed: anotherobj, } pub fn new() -> obj { let data = vec![1,2,3]; obj { processed: anotherobj { original: data, // ... } } } // access obj.processed.original, can create getter `fn original(&self)` 2. shared pointer design
straightforward use of refcounted pointers:
use std::rc::rc; pub struct anotherobj { original: rc<vec<i8>>, } pub struct obj { original: rc<vec<i8>>, processed: anotherobj, } pub fn new() -> obj { let data = rc::new(vec![1,2,3]); obj { original: data.clone(), processed: anotherobj { original: data.clone(), } } } 3. raw pointers
options 1. , 2. bring peace of mind of safe rust gods, therefore don't recommend third option. still post here completeness. note: compiles, never tested @ runtime, may bite. there's safe code below you'll have go in unsafe land when want dereference raw pointer.
use std::ptr; pub struct anotherobj { original: *mut vec<i8>, } pub struct obj { original: vec<i8>, processed: anotherobj, } pub fn new() -> obj { let data = vec![1,2,3]; let mut obj = obj { original: data, processed: anotherobj { original: ptr::null_mut(), } }; obj.processed.original = &mut obj.original *mut vec<i8>; obj }
Comments
Post a Comment