《Rust程式設計與專案實戰》(朱文偉,李建英)【摘要 書評 試讀】- 京東圖書 (jd.com)
在Rust中,結構體(Struct)是一種自定義資料型別,它允許我們將多個相關的值組合在一起,形成一個更復雜的資料結構。結構體在Rust中被廣泛應用於組織和管理資料,具有靈活性和強大的表達能力。本節將詳細介紹Rust中結構體的概念、定義語法、方法以及相關特性,並提供程式碼示例來幫助讀者更好地理解結構體的使用方法。
8.3.1 結構體的定義
Rust 中的結構體與元組都可以將若干型別不一定相同的資料捆綁在一起形成整體,但結構體的每個成員和其本身都有一個名字,這樣訪問它的成員的時候就不用記住下標了。元組常用於非定義的多值傳遞,而結構體用於規範常用的資料結構。結構體的每個成員叫作“欄位”。
在Rust中,我們可以使用struct關鍵字定義一個結構體。結構體允許我們定義多個欄位(Fields),每個欄位都有自己的型別和名稱。透過將欄位組合在一起,可以建立自己的資料型別,以便更好地表示和運算元據。以下是一個簡單的結構體定義的示例:
struct Point { x: i32, y: i32, }
在上述示例中,我們定義了一個名為Point的結構體,它具有兩個欄位x和y,分別是i32型別的整數。再來看一個結構體定義:
struct Site { domain: String, name: String, nation: String, found: u32 }
注意:如果你常用C/C++,請記住在Rust中struct語句僅用來定義,不能宣告例項,結尾不需要“;” 符號,而且每個欄位定義之後用“,”分隔。
8.3.2 結構體例項化
一旦定義了結構體,可以透過例項化結構體來建立具體的物件。可以透過以下兩種方式例項化結構體:
1)宣告式例項化
let p = Point { x: 10, y: 20 };
在上述示例中,我們使用Point結構體的定義建立了一個名為p的例項,同時指定了欄位x和y 的值。
2)可變例項化
如果需要修改結構體的欄位值,可以在定義結構體變數時加上mut,程式碼如下:
let mut p = Point { x: 10, y: 20 }; p.x = 30; p.y = 40;
在上述示例中,我們建立了一個可變例項p,並修改了欄位x和y的值。
Rust很多地方受JavaScript的影響,在例項化結構體的時候用JSON物件的key: value語法來實現,比如:
let mysite = Site { domain: String::from("www.qq.com"), name: String::from("qq"), nation: String::from("China"), found: 2024 };
如果你不瞭解 JSON 物件,可以不用管它,記住格式就可以了:
結構體類名 {
欄位名 : 欄位值,
...
}
這樣的好處是不僅使程式更加直觀,還不需要按照定義的順序來輸入成員的值。如果正在例項化的結構體有欄位名稱和現存變數名稱一樣,可以簡化書寫:
let domain = String::from("www.qq.com"); let name = String::from("qq"); let runoob = Site { domain, // 等同於 domain : domain, name, // 等同於 name : name, nation: String::from("China"), traffic: 2024 };
有這樣一種情況:想要新建一個結構體的例項,其中大部分屬性需要被設定成與現存的一個結構體屬性一樣,僅需更改其中一兩個欄位的值,可以使用結構體更新語法:
let site = Site { domain: String::from("www.qq.com"), name: String::from("qq"), ..qq };
注意:..qq後面不可以有逗號。這種語法不允許一成不變地複製另一個結構體例項,意思就是至少重新設定一個欄位的值,才能引用其他例項的值。
8.3.3 結構體的方法
在Rust中,結構體可以擁有自己的方法。方法是與結構體關聯的函式,可以透過結構體例項呼叫。以下是一個結構體方法的示例:
struct Rectangle { width: u32, height: u32, } impl Rectangle { //使用關鍵字impl來定義結構體的一個或多個方法 fn area(&self) -> u32 { //用關鍵字fn定義具體的函式 self.width * self.height } } fn main() { let rect = Rectangle { width: 10, height: 20 }; let area = rect.area(); println!("Area: {}", area); }
在上述示例中,我們定義一個名為Rectangle的結構體,併為其實現一個area方法,用於計算矩形的面積。在main函式中,我們建立一個Rectangle例項rect,然後透過呼叫area方法計算矩形的面積並列印出來。
8.3.4 結構體的關聯函式
除例項方法外,結構體還可以定義關聯函式(Associated Functions)。關聯函式是直接與結構體關聯的函式,不需要透過結構體例項來呼叫。以下是一個關聯函式的示例:
struct Circle { radius: f64, } impl Circle { fn new(radius: f64) -> Circle { Circle { radius } } fn area(&self) -> f64 { std::f64::consts::PI * self.radius * self.radius } } fn main() { let circle = Circle::new(5.0); let area = circle.area(); println!("Area: {}", area); }
在上述示例中,我們定義一個名為Circle的結構體,併為其實現一個關聯函式new,用於建立一個新的Circle例項。在main函式中,我們透過呼叫Circle::new關聯函式建立一個Circle例項circle,然後透過呼叫area方法計算圓的面積並列印出來。
8.3.5 結構體的特性
Rust的結構體具有兩個特性:元組結構體(Tuple Struct)和類單元結構體(Unit-Like Struct)。
元組結構體是一種特殊型別的結構體,它沒有命名的欄位,只有欄位的型別。元組結構體使用圓括號而不是花括號來定義。比如:
struct Color(i32, i32, i32);
在上述示例中,我們定義了一個名為Color的元組結構體,它包含3個i32型別的欄位。
類單元結構體是一種沒有欄位的結構體,類似於空元組。比如:
struct Empty;
在上述示例中,我們定義了一個名為Empty的類單元結構體。