@@ -230,8 +230,9 @@ fn add_one(num: &int) -> int {
230
230
```
231
231
232
232
Rust has a feature called 'lifetime elision,' which allows you to not write
233
- lifetime annotations in certain circumstances. This is one of them. Without
234
- eliding the lifetimes, ` add_one ` looks like this:
233
+ lifetime annotations in certain circumstances. This is one of them. We will
234
+ cover the others later. Without eliding the lifetimes, ` add_one ` looks like
235
+ this:
235
236
236
237
``` rust
237
238
fn add_one <'a >(num : & 'a int ) -> int {
@@ -449,6 +450,80 @@ This is the simplest kind of multiple ownership possible. For example, there's
449
450
also ` Arc<T> ` , which uses more expensive atomic instructions to be the
450
451
thread-safe counterpart of ` Rc<T> ` .
451
452
453
+ ## Lifetime Elision
454
+
455
+ Earlier, we mentioned 'lifetime elision,' a feature of Rust which allows you to
456
+ not write lifetime annotations in certain circumstances. All references have a
457
+ lifetime, and so if you elide a lifetime (like ` &T ` instead of ` &'a T ` ), Rust
458
+ will do three things to determine what those lifetimes should be.
459
+
460
+ When talking about lifetime elision, we use the term 'input lifetime' and
461
+ 'output lifetime'. An 'input liftime' is a lifetime associated with a parameter
462
+ of a function, and an 'output lifetime' is a lifetime associated with the return
463
+ value of a function. For example, this function has an input lifetime:
464
+
465
+ ``` {rust,ignore}
466
+ fn foo<'a>(bar: &'a str)
467
+ ```
468
+
469
+ This one has an output lifetime:
470
+
471
+ ``` {rust,ignore}
472
+ fn foo<'a>() -> &'a str
473
+ ```
474
+
475
+ This one has a lifetime in both positions:
476
+
477
+ ``` {rust,ignore}
478
+ fn foo<'a>(bar: &'a str) -> &'a str
479
+ ```
480
+
481
+ Here are the three rules:
482
+
483
+ * Each elided lifetime in a function's arguments becomes a distinct lifetime
484
+ parameter.
485
+
486
+ * If there is exactly one input lifetime, elided or not, that lifetime is
487
+ assigned to all elided lifetimes in the return values of that function..
488
+
489
+ * If there are multiple input lifetimes, but one of them is ` &self ` or `&mut
490
+ self` , the lifetime of ` self` is assigned to all elided output lifetimes.
491
+
492
+ Otherwise, it is an error to elide an output lifetime.
493
+
494
+ ### Examples
495
+
496
+ Here are some examples of functions with elided lifetimes, and the version of
497
+ what the elided lifetimes are expand to:
498
+
499
+ ``` {rust,ignore}
500
+ fn print(s: &str); // elided
501
+ fn print<'a>(s: &'a str); // expanded
502
+
503
+ fn debug(lvl: uint, s: &str); // elided
504
+ fn debug<'a>(lvl: uint, s: &'a str); // expanded
505
+
506
+ // In the preceeding example, `lvl` doesn't need a lifetime because it's not a
507
+ // reference (`&`). Only things relating to references (such as a `struct`
508
+ // which contains a reference) need lifetimes.
509
+
510
+ fn substr(s: &str, until: uint) -> &str; // elided
511
+ fn substr<'a>(s: &'a str, until: uint) -> &'a str; // expanded
512
+
513
+ fn get_str() -> &str; // ILLEGAL, no inputs
514
+
515
+ fn frob(s: &str, t: &str) -> &str; // ILLEGAL, two inputs
516
+
517
+ fn get_mut(&mut self) -> &mut T; // elided
518
+ fn get_mut<'a>(&'a mut self) -> &'a mut T; // expanded
519
+
520
+ fn args<T:ToCStr>(&mut self, args: &[T]) -> &mut Command // elided
521
+ fn args<'a, 'b, T:ToCStr>(&'a mut self, args: &'b [T]) -> &'a mut Command // expanded
522
+
523
+ fn new(buf: &mut [u8]) -> BufWriter; // elided
524
+ fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a> // expanded
525
+ ```
526
+
452
527
# Related Resources
453
528
454
529
Coming Soon.
0 commit comments