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