更改结构中一个字段的简单方法?

use*_*932 4 rust

我有以下代码:

#[derive(Clone, Copy)]
struct Point {
    x: f64,
    y: f64,
    z: f64
}

impl Point {
    fn set_z(&self, val: f64) -> Point {
        Point{x: self.x, y: self.y, z: val}
    }
}

struct Boo {
    point: Point
}

impl Boo {
    fn point(&self) -> &Point { &self.point }
    fn set_point(&mut self, val: &Point) { self.point = *val; }
}

fn main() {
    let mut boo = Boo{point:Point{x: 0., y: 0., z: 0.}};
    let new_p = boo.point().set_z(17.);
    boo.set_point(&new_p);
}
Run Code Online (Sandbox Code Playgroud)

事实上,我有一堆像字段这样的结构BooPoint而且通常我只需要更改其中的一个字段。

所以我可以

  1. 实施数百万种方法,例如:

    impl Boo {
        fn set_x(&mut self, val: f64) { self.point.x = val; }
        fn set_y(&mut self, val: f64) { self.point.y = val; }
        //...
    }
    
    Run Code Online (Sandbox Code Playgroud)

    这太无聊了,如果有两个、三个字段point1point2比如 等等,我将被大量的这些方法所淹没。

  2. 问题顶部描述的方法看起来更好,因为每个字段只需要两个方法,但我必须分两步进行修改:获取点和设置点。

所以对我来说理想的方法是这样的:

boo.set_point(boo.point().set_z(17.));
Run Code Online (Sandbox Code Playgroud)

但这是不可能的,因为要实现这一点,我需要以某种方式同时读取和写入引用。

如何简化Point为模块用户仅设置一个字段的过程?

Luk*_*odt 5

为什么不公开这些字段?

#[derive(Clone, Copy)]
struct Point {
    pub x: f64,
    pub y: f64,
    pub z: f64
}

struct Boo {
    pub point: Point
}

boo.point.z = 17.0;
Run Code Online (Sandbox Code Playgroud)

封装是一件好事,您通常不希望每个人都更改类型的内部字段。但这仅当存在该字段不得采用的非法值或者其他值依赖于该字段(例如缓存)时才是必要的。但如果情况并非如此(在您的示例中看起来并非如此),那么只需将这些字段标记为公共即可。