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

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

Open
laerson opened this issue Jan 12, 2025 · 0 comments

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!

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

1 participant