CodeBlanks Logo Icon CodeBlanks

Elision rules

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:

  1. Each reference parameter gets its own lifetime.
  2. If there is exactly one reference parameter, its lifetime is given to all returned references.
  3. If one of the parameters is &self or &mut self, the lifetime of self is 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 self

The 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

main.rs
fn main() {
    // buraya yaz
}

Sample solution

main.rs
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: &amp;str, b: &amp;str) -&gt; &amp;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

Question
fn kisalt(s: &str) -> ____ {
    s.get(..3).unwrap_or(s)
}
Answer
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

All lessons in Intermediate