As far as I understand, you're mostly right, except the structures bit.

Disregarding that it is not possible to use several lifetime
parameters yet, I see only one slight mistake: `s: MyStruct<'a>` does
not imply that `s` variable has any specific lifetime. If it is a
local variable, then it has 'lexical' lifetime; if it is a field in a
structure, it has lifetime of the structure instance.

 I guess what you meant is this:

s: &'a MyStruct<'a>

Here `s` pointer have lifetime 'a, as well as `s.r_int`.

BTW, you came up with very nice math-like analogy, it helped me
understand this thing even more. Thanks :)

2013/9/29 Gábor Lehel <[email protected]>:
> 'self is not special in any way, except that the compiler has historical
> baggage such that 'self is the only name it lets you use for a lifetime
> parameter on a struct. But that's a bug. In the ideal platonic Rust in the
> sky, you can have any number of lifetime parameters on a struct with
> whatever names you prefer.
>
> The way I've found to think about lifetimes is that if you have:
>
> r_int: &'a int
>
> then 'a refers to a span of time (a scope, a lifetime) such that
> lifetime_of(r_int) <= 'a <= lifetime_of(*r_int). (Where *r_int is intended
> metaphorically to refer to the original object r_int was created from, not
> the result of the *r_int expression itself.) So 'a is a kind of stand
> between to ensure that r_int does not outlive the object it refers to.
>
> If you have
>
> fn foo<'a>(r_int: &'a int) -> &'a int
>
> then just like any other generics argument, the lifetime 'a is chosen by the
> caller of `foo` (as inferred by the compiler). Typically the caller will
> have an int object (i: int), then borrow a reference to it (r_int: &'a int =
> &i) which it passes to `foo`, and then 'a will be the lifetime of the int.
> `foo` will then have to return a reference to (an int that lives at least as
> long). In practice this could either be the r_int it got as argument, or a
> static int.
>
> `fn foo(arg: &int)` is shorthand for an anonymous lifetime parameter: `fn
> foo<'a>(arg: &'a int)`
>
> In the return type position `fn foo() -> &int` is short for `fn foo<'a>() ->
> &'a int`, meaning `foo` has to return a reference to (an int that lives as
> long as any lifetime the caller could choose), which in practice means that
> it has to be 'static. I believe you are or will be required to write
> &'static explicitly in these cases to avoid confusion.
>
> With a struct it's not much different.
>
> s: MyStruct<'a> means lifetime_of(s) <= 'a
> s: MyStruct<'a, 'b> means lifetime_of(s) <= 'a && lifetime_of(s) <= 'b
>
> If you have
>
> struct MyStruct<'self> {
>     r_int: &'self int
> }
>
> s: MyStruct<'a>
>
> then lifetime_of(s) <= 'a && lifetime_of(s.r_int) <= 'a. (Which is trivial
> because lifetime_of(s) == lifetime_of(s.r_int).)
>
> Basically, every object has a lifetime - from its creation to its
> destruction - but a lifetime parameter or argument typically refers to the
> lifetime of something else, which the object itself must not or does not
> outlive.
>
> (Please yell at me if I got any of this wrong.)
>
>
>
> On Sun, Sep 29, 2013 at 5:23 PM, Oren Ben-Kiki <[email protected]> wrote:
>>
>> Ok, color me confused... perhaps there's somewhere that explains 'self on
>> more detail? For example, _why_ does the example below not work without the
>> explicit <'self>? It seems like it should.
>>
>> I have yet to truly understand the whole 'self thing. When I first read
>> about lifetimes, my naive expectations were that:
>>
>> - Every struct has a 'self lifetime, which is basically "as long as this
>> struct exists". It doesn't matter if I have a @ of the struct or a ~ of the
>> struct or just a local variable with the struct... when the struct is
>> dropped, the lifetime ends.
>>
>> - It follows there's no need to ever annotate structs as generic with a
>> <'self> parameter - it always exists.
>>
>> - Any & in a struct is either &'self or &'static. A simple & should be
>> &'self as that makes more sense (but if Rust wants me to be explicit, fine).
>>
>> This were my "least surprise" expectations, but things don't work this
>> way... the problem is I don't have a simple mental model to replace the
>> above with, so I struggle. What _is_ 'self, exactly?
>>
>> Isn't a function fn foo(&self) -> &T the same as returning a &'self T? Why
>> would I want to say fn foo<'a>(&'a self) in the 1st place - 'a is "by
>> definition" the same as 'self? How come David's Foo example fails the borrow
>> check?
>>
>> Besides failing (my) "least surprise" expectations, the current rules also
>> seem to be a "leaky abstraction". If I have a struct that holds a ComplexT
>> member, it needs no <'self> parameter. If I then add a private member to my
>> struct to hold some &'self PartOfT (say, cached access to an internal
>> member), then boom, all uses of my struct now have to say <'self>, I can no
>> longer put it in thread-local-storage, etc. I'd expect keeping these sort of
>> cached borrowed pointers should be an internal implementation detail which
>> does not affect the users of the struct at all.
>>
>> I suppose there's a good reason for all this, and a reasonable mental
>> model I need to put in my head, but digging around the docs I didn't find
>> one... Any hints would be appreciated :-)
>>
>>
>> On Sun, Sep 29, 2013 at 5:42 PM, David Renshaw <[email protected]>
>> wrote:
>>>
>>> Cool! I think that solution is much better than mine.
>>>
>>> > But I
>>> > think that polluting traits-interfaces with lifetime annotation is
>>> > wrong. Why the trait should have lifetime annotation? It is
>>> > implementation detail.
>>>
>>> Just in case you want to see a case where it *does* make sense to put
>>> a 'self lifetime in a trait definition, here is an example:
>>>
>>> https://gist.github.com/dwrensha/db919b8e130e9eb72f0f
>>> _______________________________________________
>>> 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
>>
>
>
>
> --
> Your ship was destroyed in a monadic eruption.
>
> _______________________________________________
> 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

Reply via email to