This article is part of the Rust學習筆記 series.

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表示可變性,調用者需要滿足。

selfmut self 表示該方法調用者是值,並且由於是值所以值會移動進方法中;&self&mut self 表示該方法調用者是引用,而引用則不用在意移動之事。

移動與否一事影響很大,所以在選擇該方案前要慎重。通常見到的多是引用形式的,此時只用考慮可變性一件事。對於方法調用特殊的一點是,Rust會自動嘗試從 self&self 進行轉換。

選擇引用形式的 self 的效果類似於C++中的 const 成員函數,也類似golang中是否選擇 *

未完待續...

Renyuneyun

Arch Linux用戶;閒暇時爲FLOSS做做貢獻;認同自由軟件理念。自認唯物論者;反對任意形式的迷信;在意社會問題;拒絕先入爲主。

Renyuneyun

Join the discussion