What is lifetime elision in very simple terms?

前端 未结 1 1306
花落未央
花落未央 2020-11-27 20:20

From the Rust documentation:

Rust supports powerful local type inference in the bodies of functions, but it deliberately does not perform any reasonin

相关标签:
1条回答
  • 2020-11-27 21:20

    An item signature is the bit which gives the name and types of your function, i.e. everything you need to call it (without needing to know how it's implemented); for example:

    fn foo(x: u32) -> u32;
    

    Here's another which takes a &str reference:

    fn bar<'a>(s: &'a str) -> &'a str;
    

    In Rust, all references have an attached lifetime; this is part of the type. The above bar function says more than just "this function takes a reference to a string and returns another one". It says "this function takes a string reference, and returns another which is valid for as long as the one it's given. This is an important part of Rust's ownership system.

    However, it's annoying and a pain to specify these lifetimes every time, so Rust has "lifetime elision" (i.e. "not explicitly writing them out"). All that means is that for a few very common cases, you can leave the lifetime annotations out and Rust will implicitly add them for you. This is purely a convenience for programmers so that they don't have to write so many lifetimes in "obvious" cases.

    The rules are listed in the book, but for completeness they are:

    1. Every lifetime in the function parameters which isn't otherwise specified is different. For example:
    fn f(x: &T, y: &U)
    

    means:

    fn f<'a, 'b>(x: &'a T, y: &'b U)
    

    i.e. there's no automatic link between those lifetimes.

    1. If there's only one input lifetime, it's used for every output lifetime. For example:
    struct U<'a> {}  // struct with a lifetime parameter
    
    fn f(x: &T) -> &U
    

    becomes:

    fn f<'a>(x: &'a T) -> &'a U<'a>
    
    1. Otherwise, if there are multiple input lifetimes but one of them is &self or &mut self (i.e. it's a method), then all the elided output lifetimes get the same as self. This covers the common case that a method returns a reference to one of its fields. For example:
    impl S {
        fn get_my_item(&self, key: &str) -> &str {}
    }
    

    becomes:

    fn get_my_item<'a,'b>(&'a self, key: &'b str) -> &'a str  // use the self lifetime
    

    The documentation has some more examples.

    0 讨论(0)
提交回复
热议问题