Mutably borrow one struct field while borrowing another in a closure

允我心安 提交于 2019-11-26 13:52:05
Daniel

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));

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 a move 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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!