I'm having problems in changing a field of a struct inside of option. This is the code:
struct MyStruct {
field1 : i32,
field2 : i32,
// and many more...
}
impl MyStruct {
pub fn field1(&mut self, field1 : i32) -> &mut Self {
self.field1 = field1;
self
}
}
fn foo() -> Option<MyStruct> {
None
}
fn bar() -> Option<MyStruct> {
foo().as_mut().map(|s| s.field1(5))
}
fn main() {
bar();
}
The main idea of bar()
is to get an Option<MyStruct>
from another function returning an Option<MyStruct>
, change a field of that struct (in case the result is not None
) and return the resulting Option<MyStruct>
.
The struct implements the builder pattern, so I've used it.
In this case I get the following error:
test.rs:18:5: 18:40 error: mismatched types:
expected `core::option::Option<MyStruct>`,
found `core::option::Option<&mut MyStruct>`
(expected struct `MyStruct`,
found &-ptr) [E0308]
test.rs:18 foo().as_mut().map(|s| s.field1(5))
I've also tried to use Option.take()
and to change the signature of the builder method as pub fn field1(mut self, field1 : i32) -> Self
, but none of them work.
How can I make this code work?
I know that I could create another Option
and map every field of the input to the corresponding field of the output, but MyStruct
has a lot of fields and it is tedious.
There is no reason to use as_mut()
at all. Because you need to return MyStruct
by value, you can just map
on the option:
fn bar() -> Option<MyStruct> {
foo().map(|mut s| { s.field1(5); s })
}
That's it. You need to mark s
with mut
for the same reason you need to do so with let
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With