1

What's the difference between

let book_scores = &system.book_scores;
library.books.sort_unstable_by_key(|b| book_scores[*b]);

and

library.books.sort_unstable_by_key(|b| &system.book_scores[*b]);

?

The first one is allowed by the compiler and the second one fails with

error[E0502]: cannot borrow system as immutable because it is also borrowed as mutable

libraries is a field of system, library is an element of libraries in a for loop like
for library in &mut system.libraries {

Pablo Tato Ramos
  • 409
  • 4
  • 18
  • Please post the rest of the code and little bit of definitions for structures would be helpful. – apatniv Feb 25 '20 at 12:39

1 Answers1

2

The difference is that a closure's variable binding is shallow. Consider the following closure:

let closure = || println!("{}", a.b.c.d);

Since the closure doesn't define an a, a is borrowed from its outside environment. When actually called, the closure accesses .b.c.d on the borrowed a.

The closure doesn't try to immediately calculate a.b.c.d and borrow that. If it did, it wouldn't be able to notice changes to a.b or a.b.c or even a.b.c.d. Similarly, if it captured a.b.c on creation and accessed .d when called, it wouldn't be able to respond to changes to a.b or a.b.c.

If you need to pre-capture a part of the expression, you need to make it explicit, as your first snippet does.

user4815162342
  • 141,790
  • 18
  • 296
  • 355