let array = [40];
let mut var = 60;
for element in array.iter().filter(|&x| {*x < var}) {
var += 1; // Error
}
var += 1; // Fine again
Pour moi, ce code semble tout à fait légitime, que la fermeture devrait être terminée au moment où je réellement accès var
en dehors de celui-ci.Closures conservent la propriété des variables locales plus longtemps que prévu
error[E0506]: cannot assign to `var` because it is borrowed
--> src/main.rs:6:9
|
5 | for element in array.iter().filter(|&x| {*x < var}) {
| ---- borrow of `var` occurs here
6 | var += 1; // Error
| ^^^^^^^^ assignment to borrowed `var` occurs here
Pourquoi var
encore empruntèrent lors de l'appel var += 1
même si la portée de la fermeture devrait être déjà terminée? Le résultat est nécessaire pour accéder à var += 1
. Alors qu'il est possible de faire quelque chose comme ça sans filter
, cela rend mon code beaucoup moins clair, donc je voudrais continuer à l'utiliser.
Donc, si je comprends bien tout, l'utilisation de filter() crée une nouvelle structure contenant la fermeture (et l'emprunt val) qui existe jusqu'à ce qu'elle soit hors de portée, ce qui arrive une fois que l'itérateur est appelé La boucle est terminée et la structure du filtre est hors de portée, ce qui signifie qu'elle arrête d'emprunter val et que je peux la muter de nouveau. Dans le cas où cela est vrai, je comprends enfin comment fonctionnent les itérateurs. Merci, et sry pour mon mauvais anglais, j'écris ceci sur mon téléphone. – SleepingPanda
@SleepingPanda oui. Il crée un ['Filter'] (https: //doc.rust-lang.org/std/iter/struct.Filter.html) struct qui contient la fermeture et la fermeture tente d'emprunter immuablement 'var'. Le corps de la boucle tente de muter 'var'. La propriété de cette structure est transférée à la boucle 'for'. – Shepmaster