Also, re: the lifetimes. I'm not sure what the current status is, but I know there are some RFCs to make "obvious" lifetimes more inferred.
On Fri, Oct 17, 2014 at 12:48 PM, Clark Gaebel <[email protected]> wrote: > Oooh fun you’ve hit your first rustc bug! Great! > > https://github.com/rust-lang/rust/issues/17178 > > Niko is already working on this, so a fix is coming soon. Both of those > constructions should have failed. The correct way to fix this is: > > ``` > let weights = [ 3,5,7 ]; > let b = InBag(Bag { price: 10, weights: weights.as_slice() }); > ``` > > > > On Fri, Oct 17, 2014 at 12:30 PM, David Henningsson <[email protected]> > wrote: > >> First, big thanks to both of you, Ben and Clark, for helping out. :-) >> >> Thanks for the hint on the lifetime syntax - it's a bit hard to grasp, >> sometimes it's "Foo<'a>", sometimes it's "& 'a [Foo]", and I've seen >> examples with "Foo+'a" too. But maybe this all makes sense when I'm more >> used to the language. >> >> As for how long the pointed-to data is alive for, I think it makes sense >> to default to "the same lifetime as parent struct or enum", if the lifetime >> is not explicitly specified. >> >> Btw, for some reason this does not work: >> >> let s = InBag(Bag { price: 10, weights: &[3, 5, 7] }); /* fails with >> "borrowed value does not live long enough" and "consider using a `let` >> binding to increase its lifetime" */ >> >> But the below does, and can be used as a workaround: >> >> let b = Bag { price: 10, weights: &[3, 5, 7] }; >> let s = InBag(b); >> >> I'm sure there's an explanation to why, but if it can be fixed so that >> the compiler interprets the first as being equivalent to the second it >> would be nice. >> >> On 2014-10-17 21:01, Ben Foppa wrote: >> >> 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
