I want to collect changes to a struct and apply them all at once. The basic outline looks like this:
enum SomeEnum {
Foo,
Bar,
}
struct SomeStruct {
attrib: SomeEnum,
next_attrib: Option<SomeEnum>,
}
impl SomeStruct {
pub fn apply_changes(&mut self) {
if let Some(se) = self.next_attrib {
self.attrib = se;
}
self.next_attrib = None;
}
}
which yields the following compiler error:
error[E0507]: cannot move out of borrowed content --> src/lib.rs:13:27 | 13 | if let Some(se) = self.next_attrib { | -- ^^^^ cannot move out of borrowed content | | | hint: to prevent move, use `ref se` or `ref mut se`
I found Get an enum field from a struct: cannot move out of borrowed content and added #[derive(Clone, Copy)]
to my enum's definition.
This may work but I feel uncomfortable about (implicitly) using copying since this could generally happen to larger datatypes as well.
The actual owner is never moved out of the struct.
Is there another way to accomplish this, without exposing the Copy
/Clone
traits to all users of the enum?
It's unclear how well you follow the overall issue, but essentially, you can't assign the value to
self.attrib
if it's still owned byself.next_atrrib
. That means you need so remove the value fromself.next_attrib
and then give ownership toself.attrib
.One way to do this would be to manually replace the value. For instance, you could use
std::mem::replace
:to replace the value with
None
and take ownership of the current value asnext_attrib
. Then you can take the value and, if it isSome(_)
, you can place its content inself.attrib
.Since this is a relatively common pattern, however, there is a utility function on
Option
to handle situations where you'd like to take ownership of the contents of anOption
and set theOption
toNone
. TheOption::take
method is what you want.