Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ch10-03 Improve key paragraph in the explanation #1710

Open
bn3t opened this issue Dec 23, 2018 · 2 comments
Open

ch10-03 Improve key paragraph in the explanation #1710

bn3t opened this issue Dec 23, 2018 · 2 comments

Comments

@bn3t
Copy link

bn3t commented Dec 23, 2018

Hi,
I am banging my head over understanding how Annotated lifetimes work. I can intuitively understand the example with the longest function. I would like to get to a more formal understanding as well.

This paragraph is key in the explanation but, for me at least, stays very abstract:

The function signature now tells Rust that for some lifetime 'a, the function takes two parameters, both of which are string slices that live at least as long as lifetime 'a. The function signature also tells Rust that the string slice returned from the function will live at least as long as lifetime 'a. These constraints are what we want Rust to enforce. Remember, when we specify the lifetime parameters in this function signature, we’re not changing the lifetimes of any values passed in or returned. Rather, we’re specifying that the borrow checker should reject any values that don’t adhere to these constraints. Note that the longest function doesn’t need to know exactly how long x and y will live, only that some scope can be substituted for 'a that will satisfy this signature.

Later in the chapter, the explanation becomes more practical:

We’ve told Rust that the lifetime of the reference returned by the longest function is the same as the smaller of the lifetimes of the references passed in.

May I kindly suggest to include the latter specific explanation into the formal explanation (in bold in the following).

The function signature now tells Rust that for some lifetime 'a, the function takes two parameters, both of which are string slices that live at least as long as lifetime 'a. The function signature also tells Rust that the string slice returned from the function will live at least as long as lifetime 'a. In practice, it means that the lifetime of the reference returned by the longest function is the same as the smaller of the lifetimes of the references passed in. These constraints are what we want Rust to enforce. Remember, when we specify the lifetime parameters in this function signature, we’re not changing the lifetimes of any values passed in or returned. Rather, we’re specifying that the borrow checker should reject any values that don’t adhere to these constraints. Note that the longest function doesn’t need to know exactly how long x and y will live, only that some scope can be substituted for 'a that will satisfy this signature.

@wodny
Copy link

wodny commented Jul 15, 2019

Because this issue is still open I would like to suggest some further changes in a paragraph next to the one mentioned. There is a discussion at the user's forum suggesting that the sentence:

However, when a function has references to or from code outside that function, it becomes almost impossible for Rust to figure out the lifetimes of the parameters or return values on its own.

may be inaccurate or just wrong. The discussion includes @steveklabnik's statement on that. Unfortunately, I am unable to propose anything specific. Just pointing out contradictory statements as a Rust novice during book parsing.

@garrett-hopper
Copy link

I too was confused by Chapter 10 when I ran into this error which seemed to indicate that Rust would actually be capable of figuring out the lifetimes. After seeing the above thread, I now understand why having lifetimes explicitly stated is preferable. It would be nice if something like this was stated in the book.

fn longest<'a, 'b>(a: &'a str, b: &'b str) -> &'a str {
    if a.len() >= b.len() {
        return a
    } else {
        return b
    }
}
error[E0623]: lifetime mismatch
 --> src/main.rs:3:55
  |
3 |   fn longest<'a, 'b>(a: &'a str, b: &'b str) -> &'a str {
  |  ___________________________________-------_____-------_^
  | |                                   |
  | |                                   this parameter and the return type are declared with different lifetimes...
4 | |     if a.len() >= b.len() {
5 | |         return a
6 | |     } else {
7 | |         return b
8 | |     }
9 | | }
  | |_^ ...but data from `b` is returned here

error: aborting due to previous error

For more information about this error, try `rustc --explain E0623`.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants