fn takes_ownership(data: Data)
fn producer() -> Data
let people = [paul, john, emma];
fn producer() -> String {
String::new()
}
fn producer() -> &str {
// ???
}
&str
"looks" at some string data. Where can this data come from?Does this work?
fn producer() -> &str {
let s = String::new();
&s
}
No, we can't return a reference to local data...
error[E0515]: cannot return reference to local variable `s`
--> src/lib.rs:3:5
|
3 | &s
| ^^ returns a reference to data owned by the current function
static HELLO: &str = "hello";
fn producer() -> &'static str {
HELLO
}
h e l l o
are "baked" into your programproducer
function'static
annotation'static
for function returns or fields in types&'static T
means this reference to T
will never become invalidT: 'static
means that "if type T
has any references inside they should be 'static
"T
may have no references inside at all!&'static str
fn takes_and_returns(s: &str) -> &str {
}
Where can the returned &str
come from?
'static
s
!fn takes_many_and_returns(s1: &str, s2: &str) -> &str {
}
Where can the returned &str
come from?
'static
s1
or s2
?fn takes_many_and_returns<'a>(s1: &str, s2: &'a str) -> &'a str {
}
"Returned &str
comes from s2
"
'a
'a
, 'b
, 'c
, 'whatever
fn first_three_of_each(s1: &str, s2: &str) -> (&str, &str) {
(&s1[0..3], &s1[0..3])
}
fn main() {
let amsterdam = format!("AMS Amsterdam");
let (amsterdam_code, denver_code) = {
let denver = format!("DEN Denver");
first_three_of_each(&amsterdam, &denver)
};
println!("{} -> {}", amsterdam_code, denver_code);
}
fn first_three_of_each<'a, 'b>(s1: &'a str, s2: &'b str) -> (&'a str, &'b str) {
(&s1[0..3], &s1[0..3])
}
"The source you used in code doesn't match the tags"
error: lifetime may not live long enough
--> src/lib.rs:2:5
|
1 | fn first_three_of_each<'a, 'b>(s1: &'a str, s2: &'b str) -> (&'a str, &'b str) {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
2 | (&s1[0..3], &s1[0..3])
| ^^^^^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
|
= help: consider adding the following bound: `'a: 'b`
"Produced reference can't outlive the source"
error[E0597]: `denver` does not live long enough
--> src/main.rs:10:41
|
8 | let (amsterdam_code, denver_code) = {
| -------------- borrow later used here
9 | let denver = format!("DEN Denver");
| ------ binding `denver` declared here
10 | first_three_of_each(&amsterdam, &denver)
| ^^^^^^^ borrowed value does not live long enough
11 | };
| - `denver` dropped here while still borrowed
For more information about this error, try `rustc --explain E0597`.
fn first_three_of_each<'a, 'b>(s1: &'a str, s2: &'b str) -> (&'a str, &'b str) {
(&s1[0..3], &s2[0..3])
}
fn main() {
let amsterdam = format!("AMS Amsterdam");
let denver = format!("DEN Denver");
let (amsterdam_code, denver_code) = {
first_three_of_each(&amsterdam, &denver)
};
println!("{} -> {}", amsterdam_code, denver_code);
}
fn pick_one(s1: &'? str, s2: &'? str) -> &'? str {
if coin_flip() {
s1
} else {
s2
}
}
fn pick_one<'a>(s1: &'a str, s2: &'a str) -> &'a str {
if coin_flip() {
s1
} else {
s2
}
}
s1
or s2
fn pick_one<'a>(s1: &'a str, s2: &'a str) -> &'a str { if coin_flip() { s1 } else { s2 } } fn coin_flip() -> bool { false } fn main() { let a = String::from("a"); let b = "b"; let result = pick_one(&a, b); // drop(a); println!("{}", result); }
struct Configuration {
database_url: &str,
}
Where does the string data come from?
struct Configuration<'a> {
database_url: &'a str,
}
An instance of Configuration
can't outlive a string
that it refers to via database_url
.
or
The string can't be dropped
while an instance of Configuration
still refers to it.
where T: Debug + 'a
T
has to be printable with :?
.T
has references inside, they have to stay valid for as long as 'a
tag requires.struct
or enum
with the annotations used in function signatures and in turn with exact lifetimes of references.fn select_peer<'a>(peers: &[&'a str]) -> Option<Cow<'a, str>> {
for p in peers {
if is_up(p) {
return Some(Cow::Borrowed(p))
}
}
None
}
fn main() {}
Compiler concludes:
Returned value will not be allowed to outlive any reference in peers
list
let selected = select_peer(&peers);
T: 'static
means "Owned data or static references", owned data can be very short-lived