簡體   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