2016-08-15 69 views
1

我有以下代碼:簡單的方法來改變結構中的一個字段?

#[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); 
} 

其實,我有這樣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; } 
        //... 
    } 
    

    這也太無聊了,如果有兩個,像point1point2等三個方面上,我會被埋葬根據噸這些方法。

  2. 在問題頂部描述的方法看起來更好,因爲我只需要兩個方法每個字段,但我必須在兩個步驟進行修改:獲取點和設置點。

所以對我來說理想的方法是這樣的:

boo.set_point(boo.point().set_z(17.)); 

但這是不可能的,因爲要實現這個,我需要以某種方式讀取和寫入,同時引用。

如何簡化爲模塊的用戶設置Point的一個字段?

+0

感覺如果你有這麼多類型需要做同樣的事情,那麼你實際上有一個應該有很多實例的類型。 – Shepmaster

+0

你可以改變你的IMPL指向這樣的:'''IMPL點{ FN set_z(自我,VAL:F64) - >點{ 點{Z:VAL,*自} } ''' –

+0

在話題,我想你可以編寫自己的'derive'來爲你實現'Boo'中的'set_x','set_z'功能。但我只是一個先行者,並不能以例子來幫助你。 –

回答

2

爲什麼你不公開這些字段?

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

struct Boo { 
    pub point: Point 
} 

boo.point.z = 17.0; 

封裝是一件好事,你通常不希望每個人都改變一個類型的內部字段。但只有在有非法值的情況下,如果其他值依賴於該字段(例如緩存),則該字段不得在上採用。但是,如果情況並非如此 - 在你的例子中它看起來不是這樣 - 那麼只需將這些字段標記爲公開。

+0

你也可以將'point'公開,但不能'z',那麼你可以調用'boo.point.set_z(17.0)'。 – Shepmaster

相關問題