Your struct has a fixed size - a reference is a pointer. Which is why it requires a lifetime - how long is the pointed-to data alive for? And so you need to tell it - in your enum example, you need to say Bag<'a> (for some defined 'a). For example, Bag<'static> means the pointed-to data lives as long as the program.
On Fri, Oct 17, 2014 at 11:50 AM, David Henningsson <[email protected]> wrote: > Thanks for the answer. Deref is a new one for me, looks interesting by > means of abstraction. > > I'm also coming from the C camp but I'm not sure how to write the code > that I want in rust. Yet. :-) > > E g, here's one, somewhat related, C example that I'm not sure how to do > in Rust: > > struct bag { > int price; > int nitems; > int []items; > }; > > struct cart { /* ... */ }; > > struct shopping { > int kind; /* 0 means bag, 1 means cart */ > union { > struct bag bag; > struct cart cart; > } > } > > struct shopping* make_shopping_bag(int price, int nitems, int *items) > { > struct shopping* result = malloc(sizeof(shopping)+nitems*sizeof(int)); > result.kind = 0; > result.bag.price = price; > result.bag.nitems = nitems; > memcpy(result.bag.items, nitems*sizeof(int)); > } > > > So, the bag struct would probably look like this in Rust: > > struct Bag <'a> { > price: int, > weights: & 'a [int], > } > > 1) It feels like "weights: [int]" would be more like the way I want it, > and the declaration compiles, but i can't initialize the struct or have it > as a local variable because its size is now unkown. Even though a static > initialization like "let b = Bag { price: 10, weights: [3,5,7] }" would be > trivial to calculate the total size of, the compiler seems not to be able > to do this. > > 2) I'm not sure why this lifetime has to be explicit, should default to > "same lifetime as parent struct" IMO. > > 3) And when I try to do like: > > enum Shopping { > InBag(Bag), > InCart( /* ... */ ), > } > > I get an error: "error: wrong number of lifetime parameters: expected 1, > found 0". I've tried both "InBag('a Bag)" and "InBag(Bag + 'a)" but that > ends up with other errors instead...so no idea on what to do about that? > > > On 2014-10-17 18:37, Clark Gaebel wrote: > > Rust is not a replacement for java, it’s a replacement for C and C++. > > To solve little “puzzles” like this, i tend to ask myself “how would I > do this in C”, and then write that code in rust. Building inheritance trees > is generally the wrong way of approaching problems. In cases where it does > apply, you can still do it, but be gentle. Try not to lean on them as your > primary means of abstraction. > > Anyhow, on to your actual problem. > > Something which might be worth trying is implementing `Deref<Circle>` > and `DerefMut<Circle>` for your pancake, then having a > `DList<Box<Deref<Circle>>>` (or just use a normal &, if you want that). > > Then you can call all your circle traits after a quick call to > `.deref()`, AND your `DList` will free everything properly. > > But again, there’s probably a simpler solution that doesn’t involve > “inheritance” that you should consider. Maybe a DList of enums? Maybe just > a Vec<uint> in this case? Think about how you’d do it in C. > > Regards, > - Clark > > > > On Fri, Oct 17, 2014 at 4:27 AM, David Henningsson <[email protected]> > wrote: > >> Hmm, right. The as_* could probably useful to write a macro for. >> >> Coming from the C/Java side of things I have to figure out how this >> works in a bigger context, e g a DList or other structure owning objects >> implementing HasArea. This seems to compile, e g: >> >> impl Pancake { >> fn as_box_circle(&self) -> Box<Circle> { box self.circle } >> } >> >> fn make_pancake(dl: &mut DList<Box<HasArea>>) { >> let p = Pancake { circle: Circle { x: 0f64, y: 0f64, radius: 1f64 >> }, is_tasty: true }; >> dl.push(p.as_box_circle()); >> } >> >> But I'd assume that make_pancake would now make a copy of the pancake's >> circle, rather than taking ownership of the entire pancake, right? The >> pancake then gets dropped at function return. >> >> In this simple example perhaps this does not make that much of a >> difference though, but if you imagine a C struct like: >> >> struct list { >> list *next; >> circle *data; >> } >> >> You can now put a pointer to a pancake as data, use it as a circle, and >> when you finally free the list and the data that goes with it, the >> entire pancake will be freed. This you cannot do in rust...or can you? >> >> >> On 2014-10-17 07:59, Clark Gaebel wrote: >> > impl Pancake { >> > fn as_circle(&self) -> &Circle { &self.circle } >> > fn as_mut_circle(&mut self) -> &mut Circle { &mut self.circle } >> > } >> > >> > The compiler will optimize trivial functions, except cross-crate. In >> > those cases, use an #[inline] annotation. >> > >> > >> > >> > On Thu, Oct 16, 2014 at 10:57 PM, David Henningsson <[email protected] >> > <mailto:[email protected]> <[email protected]>> wrote: >> > >> > This is probably a previously asked question, but I couldn't find >> > it on >> > Google, so... >> > >> > Let's extend the Circle example from the guide a little: >> > >> > struct Circle { >> > x:f64, >> > y:f64, >> > radius:f64, >> > } >> > >> > trait HasArea { >> > fn area(&self)-> f64; >> > } >> > >> > impl HasArea for Circle { >> > fn area(&self)-> f64 { >> > std::f64::consts::PI * (self.radius * self.radius) >> > } >> > } >> > >> > struct Pancake { >> > circle: Circle, >> > is_tasty: bool, >> > } >> > >> > >> > ...now, what is the easiest way I can implement HasArea for >> > Pancake? I >> > could do this: >> > >> > impl HasArea for Pancake { >> > fn area(&self) -> f64 { self.circle.area() } >> > } >> > >> > ...but that means a lot of boiler-plate code, especially if >> > HasArea has >> > many methods. Hopefully rust will just inline/optimise the >> > redirection >> > away in most cases to avoid the runtime cost, but is there a >> > smarter or >> > more idiomatic way of doing this? >> > >> > // David >> > >> > _______________________________________________ >> > Rust-dev mailing list >> > [email protected] >> > https://mail.mozilla.org/listinfo/rust-dev >> > >> > >> >> > > > _______________________________________________ > Rust-dev mailing list > [email protected] > https://mail.mozilla.org/listinfo/rust-dev > >
_______________________________________________ Rust-dev mailing list [email protected] https://mail.mozilla.org/listinfo/rust-dev
