我在更改选项内部结构的字段时遇到问题.这是代码:
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();
}
Run Code Online (Sandbox Code Playgroud)
主要思想bar()是Option<MyStruct>从另一个函数返回一个Option<MyStruct>,更改该结构的字段(如果结果不是None)并返回结果Option<MyStruct>.
结构实现了构建器模式,所以我使用它.
在这种情况下,我收到以下错误:
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))
Run Code Online (Sandbox Code Playgroud)
我也尝试使用Option.take()和更改构建器方法的签名pub fn field1(mut self, field1 : i32) -> Self,但它们都不起作用.
如何使此代码有效?
我知道我可以创建另一个Option并将输入的每个字段映射到输出的相应字段,但是MyStruct有很多字段,这很乏味.
说实话,我会用显而易见的方式来做:
fn bar() -> Option<MyStruct> {
let mut val = foo();
if let Some(ref mut s) = val {
s.field1(5);
}
val
}
Run Code Online (Sandbox Code Playgroud)
它比 using 更长map,但我发现 usingmap进行变异很不舒服,而且我选择的显式变异也会产生更好的组装。
根本没有理由使用as_mut().因为您需要MyStruct按值返回,所以您可以map选择:
fn bar() -> Option<MyStruct> {
foo().map(|mut s| { s.field1(5); s })
}
Run Code Online (Sandbox Code Playgroud)
而已.您需要s使用mut相同的原因进行标记let.