Function lifetimes
- Rust course
- Intermediate
- Lesson 15/115
- 4 min
Use lifetimes in function signatures.
Function lifetimes
If the returned reference depends on only one parameter, giving the lifetime only to that one frees the caller:
fn once<'a>(s: &'a str, ayrac: &str) -> &'a str {
match s.find(ayrac) {
Some(i) => &s[..i],
None => s,
}
}The lifetime of ayrac is unrelated to the return; it can be dropped right after the call. Had we given 'a to both parameters, the separator would have to live needlessly long.
Different lifetimes
If two parameters need lifetimes independent of each other, two lifetime parameters are used:
fn sec<'a, 'b>(birinci: &'a str, _ikinci: &'b str) -> &'a str {
birinci
}Looking at the signature, the compiler knows _ikinci can be dropped before the result. The function body can't do more than the signature promises: trying to return _ikinci is a compile error.
Practice Before the separator
Write the once function above. For let metin = "ad=Ece";, create the separator as String::from("=") in an inner block, assign the result to a variable outside the block, and print it after the block.
Starter code
fn main() {
// buraya yaz
}Sample solution
fn once<'a>(s: &'a str, ayrac: &str) -> &'a str {
match s.find(ayrac) {
Some(i) => &s[..i],
None => s,
}
}
fn main() {
let metin = "ad=Ece";
let sonuc;
{
let a = String::from("=");
sonuc = once(metin, &a);
}
println!("{}", sonuc);
}Expected output
ad
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Why doesn't <code>fn f<'a>(x: &str) -> &'a str { let s = String::from("a"); &s }</code> compile?
- A reference to a local value can't be returned; s is dropped at the end of the function Correct answer
- 'a is unused
- x is unused
- It compiles
Explanation: The returned reference must either come from a parameter or be 'static. Return a String for newly produced data.
2 Only the first parameter
fn once<'a>(s: &'a str, ayrac: ____) -> &'a str {
match s.find(ayrac) {
Some(i) => &s[..i],
None => s,
}
}
fn once<'a>(s: &'a str, ayrac: &str) -> &'a str {
match s.find(ayrac) {
Some(i) => &s[..i],
None => s,
}
}
Explanation: Since the separator isn't part of the return, it needs no lifetime annotation.
3 Signature and meaning
| Term | Meaning |
|---|---|
(x: &'a str, y: &'a str) -> &'a str |
Return tied to both |
(x: &'a str, y: &str) -> &'a str |
Return tied only to x |
fn f(x: &str) -> String |
No lifetime needed |
fn f<'a>() -> &'a str |
Can only be 'static |