简体   繁体   中英

Rust: Why passing unused (_) parameter to function changes the outcome

Why below snippet errors out

fn print() -> &str
{
   let name2 = "blah";
   return &name2;
}

fn main() {
   let x = print();
   println!("{}", x);
}

but not this

fn print(_: &str) -> &str
{
   let name2 = "blah";
   return &name2;
}

fn main() 
{
   let x = print("");
   println!("{}", x);
}

The only difference is the additional parameter which is ignored in the last case

The error message tells you quite clearly why the first snippet fails:

 1 | fn print() -> &str | ^ expected named lifetime parameter

you're returning a reference , references must have a lifetime to indicate their validity. You don't provide a lifetime and rustc's rules don't provide any either, so the compilation fails.

In the second snippet, you pass in a reference. Following lifetime elision :

If there is exactly one input lifetime position (elided or not), that lifetime is assigned to all elided output lifetimes.

rustc will use the input lifetime for the output, hence the second snippet is in essence

fn print(_: &'a str) -> &'a str

Since a string literal has lifetime 'static , it can be "cast down" to any lifetime (since they're all shorter), therefore returning name2 which is an &'static str does not break the contract: it will be valid for whatever the caller provides and wants.

In the first case, the declaration is missing the lifetime specifier. You could fix this declaration with the lifetime you use:

fn print() -> &'static str {
   let name2 = "blah";
   return &name2;
}

In the second one, you're using implicit lifetimes (with Rust Edition 2018).

Implicit lifetimes really means the lifetime of the function parameter is the lifetime on output. It is thus specified.

What you're implicitly declaring is this:

fn print<'a>(_: &'a str) -> &'a str {
   let name2 = "blah";
   return &name2;
}

It "works" but only because both the argument given and the implementations are based on static lifetime. Otherwise you wouldn't be able to call it. It thus adds really nothing over the first fixed version.

more on implicit anonymous lifetimes

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM