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 <di...@ubuntu.com>
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 <di...@ubuntu.com
>> <mailto:di...@ubuntu.com>> 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
>>> <di...@ubuntu.com <mailto:di...@ubuntu.com>> 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
>>> <di...@ubuntu.com <mailto:di...@ubuntu.com>
>>> > <mailto:di...@ubuntu.com> <mailto:di...@ubuntu.com>> 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
>>> > Rust-dev@mozilla.org <mailto:Rust-dev@mozilla.org>
>>> > https://mail.mozilla.org/listinfo/rust-dev
>>> >
>>> >
>>>
>>>
>>
>>
>> _______________________________________________
>> Rust-dev mailing list
>> Rust-dev@mozilla.org <mailto:Rust-dev@mozilla.org>
>> https://mail.mozilla.org/listinfo/rust-dev
>>
>>
_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev