File tree Expand file tree Collapse file tree 5 files changed +114
-0
lines changed Expand file tree Collapse file tree 5 files changed +114
-0
lines changed Original file line number Diff line number Diff line change
1
+ # Lifetimes
2
+
3
+ Lifetimes tell the compiler how to check whether references live long
4
+ enough to be valid in any given situation. For example lifetimes say
5
+ "make sure parameter 'a' lives as long as parameter 'b' so that the return
6
+ value is valid".
7
+
8
+ They are only necessary on borrows, i.e. references,
9
+ since copied parameters or moves are owned in their scope and cannot
10
+ be referenced outside. Lifetimes mean that calling code of e.g. functions
11
+ can be checked to make sure their arguments are valid. Lifetimes are
12
+ restrictive of their callers.
13
+
14
+ ## Further information
15
+
16
+ - [ Validating References with Lifetimes] ( https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html )
17
+ - [ Lifetimes (in Rust By Example)] ( https://doc.rust-lang.org/stable/rust-by-example/scope/lifetime.html )
Original file line number Diff line number Diff line change
1
+ // lifetimes1.rs
2
+ //
3
+ // The Rust compiler needs to know how to check whether supplied references are
4
+ // valid, so that it can let the programmer know if a reference is at risk
5
+ // of going out of scope before it is used. Remember, references are borrows
6
+ // and do not own their own data. What if their owner goes out of scope?
7
+ //
8
+ // Execute `rustlings hint lifetimes1` or use the `hint` watch subcommand for a hint.
9
+
10
+ // I AM NOT DONE
11
+
12
+ fn longest ( x : & str , y : & str ) -> & str {
13
+ if x. len ( ) > y. len ( ) {
14
+ x
15
+ } else {
16
+ y
17
+ }
18
+ }
19
+
20
+ fn main ( ) {
21
+ let string1 = String :: from ( "abcd" ) ;
22
+ let string2 = "xyz" ;
23
+
24
+ let result = longest ( string1. as_str ( ) , string2) ;
25
+ println ! ( "The longest string is {}" , result) ;
26
+ }
Original file line number Diff line number Diff line change
1
+ // lifetimes2.rs
2
+ //
3
+ // So if the compiler is just validating the references passed
4
+ // to the annotated parameters and the return type, what do
5
+ // we need to change?
6
+ //
7
+ // Execute `rustlings hint lifetimes2` or use the `hint` watch subcommand for a hint.
8
+
9
+ // I AM NOT DONE
10
+
11
+ fn longest < ' a > ( x : & ' a str , y : & ' a str ) -> & ' a str {
12
+ if x. len ( ) > y. len ( ) {
13
+ x
14
+ } else {
15
+ y
16
+ }
17
+ }
18
+
19
+ fn main ( ) {
20
+ let string1 = String :: from ( "long string is long" ) ;
21
+ let result;
22
+ {
23
+ let string2 = String :: from ( "xyz" ) ;
24
+ result = longest ( string1. as_str ( ) , string2. as_str ( ) ) ;
25
+ }
26
+ println ! ( "The longest string is {}" , result) ;
27
+ }
Original file line number Diff line number Diff line change
1
+ // lifetimes3.rs
2
+ //
3
+ // Lifetimes are also needed when structs hold references.
4
+ //
5
+ // Execute `rustlings hint lifetimes3` or use the `hint` watch subcommand for a hint.
6
+
7
+ // I AM NOT DONE
8
+
9
+ struct Book {
10
+ author : & str ,
11
+ title : & str ,
12
+ }
13
+
14
+ fn main ( ) {
15
+ let name = String :: from ( "Jill Smith" ) ;
16
+ let title = String :: from ( "Fish Flying" ) ;
17
+ let book = Book { author : & name, title : & title } ;
18
+
19
+ println ! ( "{} by {}" , book. title, book. author) ;
20
+ }
Original file line number Diff line number Diff line change @@ -746,6 +746,30 @@ You can call a function right where you're passing arguments to `assert!` -- so
746
746
something like `assert!(having_fun())`. If you want to check that you indeed get false, you
747
747
can negate the result of what you're doing using `!`, like `assert!(!having_fun())`."""
748
748
749
+ # LIFETIMES
750
+
751
+ [[exercises ]]
752
+ name = " lifetimes1"
753
+ path = " exercises/lifetimes/lifetimes1.rs"
754
+ mode = " compile"
755
+ hint = """
756
+ Let the compiler guide you. Also take a look at the book if you need help:
757
+ https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html"""
758
+
759
+ [[exercises ]]
760
+ name = " lifetimes2"
761
+ path = " exercises/lifetimes/lifetimes2.rs"
762
+ mode = " compile"
763
+ hint = """
764
+ What is the compiler checking? How could you change how long an owned variable lives?"""
765
+
766
+ [[exercises ]]
767
+ name = " lifetimes3"
768
+ path = " exercises/lifetimes/lifetimes3.rs"
769
+ mode = " compile"
770
+ hint = """
771
+ If you use a lifetime annotation in a struct's fields, where else does it need to be added?"""
772
+
749
773
# STANDARD LIBRARY TYPES
750
774
751
775
[[exercises ]]
You can’t perform that action at this time.
0 commit comments