Skip to content

Suggestion: Clarify the use of pattern-matching references in Listing 4-7 on Section 4.3 #4200

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

Closed
laerson opened this issue Jan 12, 2025 · 1 comment

Comments

@laerson
Copy link

laerson commented Jan 12, 2025

In [Listing 4-7] from Chapter 4 of the book, we have the following code:

for (i, &item) in bytes.iter().enumerate() {
    if item == b' ' {
        return i;
    }
}

While the text does mention that we use & in the pattern because the iterator returns references, it never clearly explains how this destructuring works or why it might be preferred to explicit dereferencing. This can be confusing when readers first encounter the pattern.

Specific Points of Confusion

  1. Demonstrating reference unpacking
    The code for (i, &item) in bytes.iter().enumerate() uses the same pattern-matching idea as:

    let a = 10;
    let &b = &a;

    However, up to this point in the book, there isn’t an example showing let &b = &a;. Introducing this syntax without a previous explanation can leave readers scratching their heads about what’s going on.

  2. Why use pattern matching instead of explicit dereference?
    The book doesn’t compare the destructuring approach to the slightly more explicit version:

    for (i, item) in bytes.iter().enumerate() {
        if *item == b' ' {
            return i;
        }
    }

    Explaining the difference (and why one might be more idiomatic) would be helpful.

Proposed Improvements

  • Add a paragraph (possibly in Section 4.2 or 4.3) demonstrating how you can “unpack” a reference with pattern syntax:

    let a = 10;
    let &b = &a; // binds the value of `a` to `b`

    and clarify that this does not mean b now shares the same address as a. It’s merely a more concise way of writing:

    let a = 10;
    let tmp = &a;
    let b = *tmp;  // now b is an i32, not a reference
  • Emphasize that destructuring is syntactic sugar
    It might help to show an example that prints addresses to prove that b has a different address in memory than a:

    fn main() {
        let a = 10;
        let &b = &a;
        println!("Addresses: &a = {:p}, &b = {:p}", &a, &b);
        // We’ll see two distinct addresses here
    }

    Such an example would reinforce that b is a completely separate integer, not a reference to a nor the same variable as a.

These clarifications would help readers see how pattern matching with references works and why the destructuring style is often preferred for brevity and clarity. It would also avoid confusion for those who are still digesting ownership, borrowing, and references.

Thank you for considering these suggestions!

@chriskrycho
Copy link
Contributor

Thanks for the feedback. I definitely get what you mean, but I think this is one of those places where if we stopped to explain all of this, it would thoroughly derail what we’re actually trying to teach here, which is about slices, not about patterns. We do provide a deeper dive into patterns in Chapter 6, and a much deeper dive in Chapter 19. If we tried to cover that here before getting through a lot of these basics, it would risk having folks “bounce off” because it would feel very abstract. And notice that we haven’t really touched on details around things like “memory addresses” in any great detail at this point; that’s also for good reason, and much the same reason: where we are in the flow of the book!

There are no doubt different approaches one could take to structuring the book, but we have the structure we have here and aren’t going to radically change it that way. Thanks, though, and I’m glad you got those things sorted out clearly for your own part!

@chriskrycho chriskrycho closed this as not planned Won't fix, can't repro, duplicate, stale Mar 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants