结构使用关联函数重新分配多个字段的干净方法?

时间:2018-10-20 02:22:54

标签: rust

考虑以下playground示例:

#[allow(dead_code)]
struct Things {
    zero: usize,
    one: usize,
    ...
    nine: usize,
}

fn do_fancy_calculation() -> (usize, usize, usize, usize, usize) {
    (1, 1, 1, 1, 1)
}

impl Things {
    fn renew(&mut self) {
        // does not work:
        // let self {one, two, five, seven, eight} = do_fancy_calculation();

        //
        let (one, two, five, seven, eight) = do_fancy_calculation();
        self.one = one;
        self.two = two;
        self.five = five;
        self.seven = seven;
        self.eight = eight;
    }
}

fn main() {
    let (zero, one, two, three, four, five, six, seven, eight, nine) =
        (0, 0, 0, 0, 0, 0, 0, 0, 0, 0);

    let mut things = Things {
        zero,
        ...
        nine,
    };

    things.renew();

    println!("{}", things.one);
}

如何在不诉诸多个one, two, five, seven, eight类型语句的情况下很好地分配给self.x = y;

之所以调用玩具关联函数renew是因为在我的实际用例中,该struct表示事物的状态,并且我需要刷新/更新/重新创建一些变量来表示状态的变化。我会以错误的方式解决用例吗?

1 个答案:

答案 0 :(得分:3)

您可以使用分配来更新self字段的子集:

*self = Self { one, two, five, seven, eight, ..*self };

这将使用匹配的局部变量更新命名字段,并使其余字段保持不变。不过,我不确定这是否比您的可读性更好。

我还会考虑其他一些选择。 do_fancy_calculation()的返回类型并没有真正传达出很多含义–也许返回struct呢?如果该函数始终用于更新Thing的状态,则可以将其设为直接更新Thing的关联函数,因此您无需将返回值合并到{{1} }。