Mutably borrow one struct field while borrowing another in a closure
This recent blog post shows a very useful pattern for this kind of problem:
Sometimes, when I want to be very precise, I will write closures in a stylized way that makes it crystal clear what they are capturing. Instead of writing
|v| ...
, I first introduce a block that creates a lot of local variables, with the final thing in the block being amove
closure (move
closures take ownership of the things they use, instead of borrowing them from the creator). This gives complete control over what is borrowed and how. In this case, the closure might look like:
In other words, the borrows are defined right with the closure and moved into the closure. This makes it totally clear that their purpose is to provide the closure with borrowed values. In context of the original question the pattern would look like this:
strct.field1.retain({
let field2 = &strct.field2;
move |v| !field2.contains(v)
});
A nice property of this code is that the borrow of field2
does not stick around after it is no longer used.
Usually the borrow checker can distinguish between the different fields of a structure, but this doesn't work within closures (lambdas).
Instead, borrow the second field outside the closure:
let field2 = &strct.field2;
strct.field1.retain(|v| !field2.contains(v));