本期文章接上期繼續講述Rust語言中的資料型別,Rust自定義資料型別主要是通過下面這兩個關鍵字來建立:

  1. 結構體( struct ): 定義一個結構體(structure)
  2. 列舉( enum ): 定義一個列舉型別(enumeration)

    其餘的型別常量則可以通過 conststatic 來建立。

一、結構體

結構體有3種類型,使用 struct 關鍵字來建立:

  • 具名結構體,具名元組
  • 元組型別結構體
  • 空結構體,不帶欄位,在泛型中很有用

1.具名結構體

// 帶有兩個欄位(field)的結構體
struct Point {
x: f32,
y: f32,
} // 結構體可以作為另一個結構體的欄位
struct Rectangle {
p1: Point,
p2: Point,
}

具名結構體內部每個成員都有自己的名字和型別,內部的成員也可以是另一個結構體。

2.元組型別結構體

// 元組結構體
struct Pair(i32, u16, bool);

可以看作是一個有名字的元組,具體使用方法和一般的元組基本類似。

3.空結構體

struct D;

空結構體的記憶體佔用為0。但是我們依然可以針對這樣的型別實現它的“成員函式”。

下面是整個樣例:

#[derive(Debug)]
struct Person<'a> {
name: &'a str,
age: u8,
} // 單元結構體
struct Nil; // 元組結構體
struct Pair(i32, f32); // 帶有兩個欄位(field)的結構體
struct Point {
x: f32,
y: f32,
} // 結構體可以作為另一個結構體的欄位
#[allow(dead_code)]
struct Rectangle {
p1: Point,
p2: Point,
} fn main() {
// 使用簡單的寫法初始化欄位,並建立結構體
let name = "Peter";
let age = 27;
let peter = Person { name, age }; // 以 Debug 方式列印結構體
println!("{:?}", peter); // 例項化結構體 `Point`
let point: Point = Point { x: 0.3, y: 0.4 }; // 訪問 point 的欄位
println!("point coordinates: ({}, {})", point.x, point.y); // 使用結構體更新語法建立新的 point,這樣可以用到之前的 point 的欄位
let new_point = Point { x: 0.1, ..point }; // `new_point.y` 與 `point.y` 一樣,因為這個欄位就是從 `point` 中來的
println!("second point: ({}, {})", new_point.x, new_point.y); // 使用 `let` 繫結來解構 point
let Point { x: my_x, y: my_y } = point; let _rectangle = Rectangle {
// 結構體的例項化也是一個表示式
p1: Point { x: my_y, y: my_x },
p2: point,
}; // 例項化一個單元結構體
let _nil = Nil; // 例項化一個元組結構體
let pair = Pair(1, 0.1); // 訪問元組結構體的欄位
println!("pair contains {:?} and {:?}", pair.0, pair.1); // 解構一個元組結構體
let Pair(integer, decimal) = pair; println!("pair contains {:?} and {:?}", integer, decimal);
}

二、列舉

Rust的列舉(enum)型別,跟C語言的列舉有點接近,然而更強大,事實上是代數資料型別(Algebraic Data Type)。

//一個代表東南西北四個方向的列舉
enum Direction {
West,
North,
Sourth,
East,
}

Rust中的列舉實現的功能不止這些,例如還闊以枚舉出其他型別資料,例如:

enum SpecialPoint {
Point {
x: i32,
y: i32,
},
Special(String),
}

如何使用列舉:和struct的成員訪問符號.不同的是,列舉型別要想訪問其成員幾乎都要用到模式匹配。你可以寫一個Direction::West,注意你絕對不能寫成Direction.West。

樣例:

// 該屬性用於隱藏對未使用程式碼的警告。
#![allow(dead_code)] // 建立一個 `enum`(列舉)來對 web 事件分類。注意變數名和型別共同指定了 `enum`
// 取值的種類:`PageLoad` 不等於 `PageUnload`,`KeyPress(char)` 不等於
// `Paste(String)`。各個取值不同,互相獨立。
enum WebEvent {
// 一個 `enum` 可以是單元結構體(稱為 `unit-like` 或 `unit`),
PageLoad,
PageUnload,
// 或者一個元組結構體,
KeyPress(char),
Paste(String),
// 或者一個普通的結構體。
Click { x: i64, y: i64 }
} // 此函式將一個 `WebEvent` enum 作為引數,無返回值。
fn inspect(event: WebEvent) {
match event {
WebEvent::PageLoad => println!("page loaded"),
WebEvent::PageUnload => println!("page unloaded"),
// 從 `enum` 裡解構出 `c`。
WebEvent::KeyPress(c) => println!("pressed '{}'.", c),
WebEvent::Paste(s) => println!("pasted \"{}\".", s),
// 把 `Click` 解構給 `x` and `y`。
WebEvent::Click { x, y } => {
println!("clicked at x={}, y={}.", x, y);
},
}
} fn main() {
let pressed = WebEvent::KeyPress('x');
// `to_owned()` 從一個字串切片中建立一個具有所有權的 `String`。
let pasted = WebEvent::Paste("my text".to_owned());
let click = WebEvent::Click { x: 20, y: 80 };
let load = WebEvent::PageLoad;
let unload = WebEvent::PageUnload; inspect(pressed);
inspect(pasted);
inspect(click);
inspect(load);
inspect(unload);
}

其它

作為碼農,伺服器可以說跟我們簡直不可分割啊,推薦幾個自己親身使用過的雲伺服器平臺給大家,有需要小夥伴可以自行檢視:

1.阿里雲:https://www.aliyun.com/?source=5176.11533457&userCode=mszy7nm5

2.騰訊雲:https://curl.qcloud.com/jgwhoTBS