What is lifetime elision in very simple terms?

China☆狼群 提交于 2019-11-26 08:30:21

问题


From the Rust documentation:

Rust supports powerful local type inference in the bodies of functions, but it deliberately does not perform any reasoning about types for item signatures. However, for ergonomic reasons, a very restricted secondary inference algorithm called “lifetime elision” does apply when judging lifetimes. Lifetime elision is concerned solely with inferring lifetime parameters using three easily memorizable and unambiguous rules. This means lifetime elision acts as a shorthand for writing an item signature, while not hiding away the actual types involved as full local inference would if applied to it.

I don\'t understand what this means. What are item signatures? What does \"infer lifetime parameters\" mean? Some examples or analogies would be helpful.


回答1:


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.



来源:https://stackoverflow.com/questions/40325690/what-is-lifetime-elision-in-very-simple-terms

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!