Hi,

I'm trying to get my head around lifetime parameters. I think I mostly get
them, for the simple
cases anyway, but there are couple of examples that are leaving me confused.

Copied some of the example code here from
http://smallcultfollowing.com/babysteps/blog/2012/12/30/lifetime-notation/:

  struct StringReader { value: &str, count: uint }
  impl StringReader {
      fn new(value: &self/str) -> StringReader/&self { StringReader {
value: value, count: 0 } }
  }
  fn remaining(s: &StringReader) -> uint { return s.value.len() - s.count; }
  fn value(s: &v/StringReader) -> &v/str { return s.value; }

1. Why is the lifetime name sometimes before a type and sometimes after the
type. For example in the
   return types of the following two functions:
     fn new(value: &self/str) -> StringReader/&self { .. }
     fn value(s: &v/StringReader) -> &v/str { .. }
   And I think there was a mention that in general the notation is just a
shorthand for &lf1/(type/&lf2);
   what's the difference between the two lifetimes lf1 and lf2 and why do
we need two of them?

2. In the 'new' method, is the 'self' in the parameter 'value: &self/str'
just a random name for
   the lifetime parameter or does this refer somehow to the 'self' type (in
which case I'd be ever
   more confused, I guess :-):
    fn new(value: &self/str) -> StringReader/&self { StringReader { value:
value, count: 0 } }

3. In the 'new' method, we are actually building a new instance of a type
with a lifetime as restricted
   by the 'value' parameter. As far as I understand, this would mean that
the type instance would have to be
   built in the same stack frame as where the variable binding defining the
lifetime parameter precides.
   I can see how this could work if the lifetime parameter comes from the
directly calling function, such as:
     fn foo() {
       let s = ~"foobar";
       let sr = StringReader::new(s);
       ..
     }
   Now, using the 'build rvalue directly in calling stack' ABI trick, this
would make sense.

   But how about if the string has a lifetime beyond the calling function,
such as:
     fn foo(s : &str) {
       let sr = StringReader::new(s);
       ...
       sr
     }
     fn bar() {
       let s = ~"foobar";
       let sr = foo(s);
     }
   Now, for the lifetime of StringReader to match the lifetime of the
string, it AFAIK would need to be
   stored in the stack frame of 'bar' instead of the stackframe of 'foo'.
Does this actually happen (e.g. the
   compiler is able to preallocate the correct slots in the stack), is
there some other magic going on or
   would this just be a compile error?

Sami
_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to