繁体   English   中英

为什么Rust的方法文档使用单独的构建器结构作为示例?

[英]Why does Rust's documentation for methods use a separate builder struct as an example?

我正在浏览结构和方法文档 ,并想知道为什么文档使用这个例子:

struct Circle {
    x: f64,
    y: f64,
    radius: f64,
}

impl Circle {
    fn area(&self) -> f64 {
        std::f64::consts::PI * (self.radius * self.radius)
    }
}

struct CircleBuilder {
    x: f64,
    y: f64,
    radius: f64,
}

impl CircleBuilder {
    fn new() -> CircleBuilder {
        CircleBuilder { x: 0.0, y: 0.0, radius: 1.0, }
    }

    fn x(&mut self, coordinate: f64) -> &mut CircleBuilder {
        self.x = coordinate;
        self
    }

    fn y(&mut self, coordinate: f64) -> &mut CircleBuilder {
        self.y = coordinate;
        self
    }

    fn radius(&mut self, radius: f64) -> &mut CircleBuilder {
        self.radius = radius;
        self
    }

    fn finalize(&self) -> Circle {
        Circle { x: self.x, y: self.y, radius: self.radius }
    }
}

fn main() {
    let c = CircleBuilder::new()
            .x(1.0)
            .y(2.0)
            .radius(2.0)
            .finalize();

    println!("area: {}", c.area());
    println!("x: {}", c.x);
    println!("y: {}", c.y);
}

我稍微修改过的代码较小,看起来完全一样:

struct Circle {
    x: f64,
    y: f64,
    radius: f64,
}


impl Circle {
    fn new() -> Circle {
        Circle { x: 0.0, y: 0.0, radius: 1.0, }
    }

    fn x(&mut self, coordinate: f64) -> &mut Circle {
        self.x = coordinate;
        self
    }

    fn y(&mut self, coordinate: f64) -> &mut Circle {
        self.y = coordinate;
        self
    }

    fn radius(&mut self, radius: f64) -> &mut Circle {
        self.radius = radius;
        self
    }

    fn area(&self) -> f64 {
        std::f64::consts::PI * (self.radius * self.radius)
    }

    fn finalize(&self) -> Circle {
        Circle { x: self.x, y: self.y, radius: self.radius }
    }
}

fn main() {
    let c = Circle::new()
            .x(1.0)
            .y(2.0)
            .radius(2.0)
            .finalize();

    println!("area: {}", c.area());
    println!("x: {}", c.x);
    println!("y: {}", c.y);
}

一般来说, CircleCircleBuilder不是一回事,因此将它们视为不同类型是有意义的。 在你的例子中,一旦Circle被“敲定”,实际上没有什么能阻止某人调用构建器方法( xyradius ) - 没有什么可以强制执行它。 用户还可能不清楚哪种方法用于构建,哪些方法用于构造的对象。 Rust有一个类型系统,可以用来静态避免这样的错误 - 使用它是有道理的!

在其他情况下,最终化步骤可能不那么简单 - 例如打开文件,执行其他I / O或计算其他一些私有字段(在构建构建器时初始化是没有意义的)。

请注意, CircleBuilder impl仅包含可以链接在一起的方法(它们返回一个&mut CircleBuilder ),一个初始化,一个返回一个Circle

当有人想要通过多个步骤“递增地”创建对象并将这些方法与例如暴露对象属性的方法分开时,这是有道理的。

你的代码很好 - 这是一个偏好的问题。 我可能只会创建一个new(x: f64, y: f64, radius: f64)方法,它会立即构建一个完整的Circle ,如Circle::new(1.0, 2.0, 2.0) new(x: f64, y: f64, radius: f64) Circle::new(1.0, 2.0, 2.0)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM