Elision rules
- Rust course
- Intermediate
- Lesson 17/115
- 4 min
Learn the lifetime elision rules.
Elision rules
The reason you don't need to write lifetimes in most functions is the compiler's three elision rules:
- Each reference parameter gets its own lifetime.
- If there is exactly one reference parameter, its lifetime is given to all returned references.
- If one of the parameters is
&selfor&mut self, the lifetime ofselfis given to the return.
fn kisalt(s: &str) -> &str // rule 2: fn kisalt<'a>(s: &'a str) -> &'a str
fn ad(&self, ek: &str) -> &str // rule 3: return tied to selfThe rules at work
No lifetimes are written in the two functions below, yet both are valid:
fn kisalt(s: &str) -> &str {
s.get(..3).unwrap_or(s)
}
struct Kisi { ad: String }
impl Kisi {
fn ad(&self) -> &str {
&self.ad
}
}get(..3) is a safe slice: if the text is shorter than 3 bytes or byte 3 falls in the middle of a character, it returns None.
Practice Signatures without lifetimes
Define the kisalt function above and the ad method of the Kisi type without writing lifetimes. Print the results of kisalt("Programlama") and Kisi { ad: "Ece".to_string() }.ad() separated by a space.
Starter code
fn main() {
// buraya yaz
}Sample solution
fn kisalt(s: &str) -> &str {
s.get(..3).unwrap_or(s)
}
struct Kisi {
ad: String,
}
impl Kisi {
fn ad(&self) -> &str {
&self.ad
}
}
fn main() {
let k = Kisi { ad: "Ece".to_string() };
println!("{} {}", kisalt("Programlama"), k.ad());
}Expected output
Pro Ece
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Why does <code>fn f(a: &str, b: &str) -> &str</code> need a lifetime?
- str always needs a lifetime
- It doesn't
- There are two reference parameters and no self; rules 2 and 3 can't apply Correct answer
- The return type is wrong
Explanation: When the rules can't determine the return lifetime, the compiler asks for an annotation (E0106).
2 Elided lifetime
fn kisalt(s: &str) -> ____ {
s.get(..3).unwrap_or(s)
}
fn kisalt(s: &str) -> &str {
s.get(..3).unwrap_or(s)
}
Explanation: Since there is a single reference parameter, the return lifetime is tied to it automatically.
3 Signature and the rule applied
| Term | Meaning |
|---|---|
fn f(x: &str) -> &str |
Rule 2 |
fn f(&self, y: &str) -> &str |
Rule 3 |
fn f(x: &str, y: &str) |
Rule 1 (no return) |
fn f(x: &str, y: &str) -> &str |
Annotation needed |