Rust中可允許自定義的類型僅有兩種: 結構體 和 枚舉 。其中枚舉用於特定場景,而結構體被設計用來支持廣泛場景。
Rust的結構體不支持繼承,所以雖然struct和trait的組合看起來像但其實不是通常意義(C++/Java)上的面向對象實踐。不過trait支持默認方法,可以部分填補該差別。
聲明結構體
基本的結構體聲明和C語言很類似:
struct Point { x: i32, y: i32, }
值得一提的是,Rust的結構體的可變性是一個整體,也就是說無法對某一個域單獨聲明可變性。
若結構體某成員是引用,其壽元需要在聲明結構體時一起聲明:
struct Product<'a> { value: i32, price: i32, name: &'a String, }
結構體也支持泛型:
struct Point<T> { a: T, b: T, }
構造一個結構體的語法也很直觀:
Point { x: 0, y: 0 }
由於Rust編譯器會自動嘗試進行類型和壽元的推導,不需要在構造時顯式聲明類型和壽元。注意Rust沒有構造函數 / 構造器(見下一節)。
方法定義
和Java等語言不同,Rust的方法定義需要單獨列出:
struct Point { x: i32, y: i32, } impl Point { fn origin() -> Self { Point { x: 0, y: 0 } } fn move_x(mut self, d: i32) { self.x += d; } }
例子中定義了一個 origin()
函數和一個 move_x()
函數。我們也可以叫 move_x()
爲方法,因爲其首個參數爲 self
,代指當前「對象」(結構體實例)。下一小節專門介紹 self
參數。
origin()
函數類似於靜態方法,其調用方式爲 Point::origin()
。其返回值類型爲 Self
,代表當前結構體類型,省去了手動輸入的麻煩。該語法在下面涉及 trait
時尤爲有用。
前面說到,Rust中沒有構造函數,因爲結構體不是類`。但習慣上,多數結構體會提供一個 new() -> Self
函數,充當構造函數。
方法的 self
參數
第一個參數爲 self
的結構體函數叫做方法,其可以是 self
mut self
&self
&mut self
中的任何一種,代表不同語義。
首先,無論何種形式,該 self
均指當前實例;mut
表示可變性,調用者需要滿足。
self
和 mut self
表示該方法調用者是值,並且由於是值所以值會移動進方法中;&self
和 &mut self
表示該方法調用者是引用,而引用則不用在意移動之事。
移動與否一事影響很大,所以在選擇該方案前要慎重。通常見到的多是引用形式的,此時只用考慮可變性一件事。對於方法調用特殊的一點是,Rust會自動嘗試從 self
向 &self
進行轉換。
選擇引用形式的self
的效果類似於C++中的const
成員函數,也類似golang中是否選擇*
。
未完待續...
您可以在Hypothesis上的該群組內進行評論,或使用下面的Disqus評論。