rust - How do I hold a collection of one struct in another where lifetimes are not predictable? -
i want manage collection of objects in object can't predict lifetime of elements in collection.
i found example in syntax of rust lifetime specifier demonstrates can't do:
struct user<'a> { name: &'a str, } // ... impls omitted struct chatroom<'a> { name: &'a str, users: hashmap<&'a str, user<'a>>, }
chatroom
holds map of user
s. each user
copy although name within user
shared reference. user
, chatroom
have explicit lifetime when joined compiler enforces user
s must live longer chatroom
they're going into.
but if user
created after chatroom
? can't use lifetimes because compiler complain. if delete user
before chatroom
? can't either.
how can chatroom
hold user
s might created after or destroyed before it? vaguely suspect done boxes implement rust's box documentation quite poor not certain.
in rust, types come in pairs: borrowed , owned counterpart. strings, borrowed version &'a str
, owned version string
. owned versions don't have lifetime parameter, because own data. doesn't mean don't contain pointers internally; string
stores data on heap, , actual string
object contains pointer data.
by using string
instead of &'a str
, can avoid issues order of construction, because can move owned data around freely (so long isn't borrowed elsewhere). example, when create user
, first need create string
, move new user
, , move user
chatroom
's hashmap
.
struct user { name: string, } struct chatroom { name: string, users: hashmap<string, user>, }
however, since need shared references, need wrap string
in type provides functionality. if writing single-threaded program, may use rc
this. if need access these references multiple threads, rc
won't work; need arc
instead.
struct user { name: rc<string>, } struct chatroom { name: string, users: hashmap<string, user>, }
in order create new rc<string>
points same string, call clone()
method on first rc<string>
.
now, string
in rc<string>
immutable, because rc
doesn't provide way mutate value (without consuming rc
). if need capability, need pair refcell
(or either mutex
or rwlock
in multi-threaded program).
struct user { name: rc<refcell<string>>, } struct chatroom { name: string, users: hashmap<string, user>, }
Comments
Post a Comment