LIFETIMES

 LIFETIMES

  • fn fruit() -> &str {
      "Grapes"
    }
  • The above function is supposed to work as per our logic, but when trying to run the code, it throws an error. 
  • &str is a reference to a string in heap and the string Grapes returning from the function will be removed from heap when the function execution is complete, since it is removed, no reference will be found when checking for it, thus the error.
  • You can avoid this error but specifying the life time of the string like given below:
  • fn fruit() -> &'static str {
      "Grapes"
    }
  • By adding the &'static str  as the return type we are specifying that the returning string should be static and it will live for the entirety of the app. 
  • Instead of setting a global life time to the string we can add a generic lifetime like below:
  • fn fullname<'l>(a:&'l str, b: &'l str) -> &'l str {
      b
    }
    
    fn main(){
      let name: &str = fullname(a:"Sanu", b:"Shilshad");
    }
  • In the above example the arguments a and b is defined inside the main thus the arguments are owned by the main fucntion.
  •  <'l>  is the lifetime specifier (can change the name l to anything).
  •  a and b has the lifetime of 'l and the return type should have the lifetime of these arguments 'l.
  • You can add lifetime for a &str inside a Structure like below:
  • struct Person<'a>{
      name: &'a str,
      age: i32
    }
  • The lifetime on parameters are called input lifetimes and the lifetime on return value is called output lifetime.
  • Three lifetime rules:
    • Compiler assigns lifetime to every parameter that's a reference. This rule is applicable to input lifetime.
    • Single input lifetime is assigned to all output lifetime. This rule is applicable to output lifetime.
    • If there are multiple input lifetime parameters, but one of them is &self or &mut self because this is a method, the lifetime of self is assigned to all output lifetime parameters.
  • Rust uses these three rules to check if a lifetime needs to be added manually by the user or not. 
  • You can add lifetime for a impl for Structure like below:
  • struct Person<'a>{
      name: &'a str,
      age: i32
    }
    
    impl<'a> Person<'a>{
        fn first_chara_in_name(&self) -> &str{
           &self.name[0..1]
        }
    }
  • The method first_chara_in_name in the above example follows the third lifetime rule.
  • You can add lifetime for a enum like below:
  • enum Animal<'a>{
      Dog {name: &'a str },
    }

Comments