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

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

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

一、結構體

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

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

1.具名結構體

  1. // 帶有兩個欄位(field)的結構體
  2. struct Point {
  3. x: f32,
  4. y: f32,
  5. }
  6. // 結構體可以作為另一個結構體的欄位
  7. struct Rectangle {
  8. p1: Point,
  9. p2: Point,
  10. }

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

2.元組型別結構體

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

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

3.空結構體

  1. struct D;

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

下面是整個樣例:

  1. #[derive(Debug)]
  2. struct Person<'a> {
  3. name: &'a str,
  4. age: u8,
  5. }
  6. // 單元結構體
  7. struct Nil;
  8. // 元組結構體
  9. struct Pair(i32, f32);
  10. // 帶有兩個欄位(field)的結構體
  11. struct Point {
  12. x: f32,
  13. y: f32,
  14. }
  15. // 結構體可以作為另一個結構體的欄位
  16. #[allow(dead_code)]
  17. struct Rectangle {
  18. p1: Point,
  19. p2: Point,
  20. }
  21. fn main() {
  22. // 使用簡單的寫法初始化欄位,並建立結構體
  23. let name = "Peter";
  24. let age = 27;
  25. let peter = Person { name, age };
  26. // 以 Debug 方式列印結構體
  27. println!("{:?}", peter);
  28. // 例項化結構體 `Point`
  29. let point: Point = Point { x: 0.3, y: 0.4 };
  30. // 訪問 point 的欄位
  31. println!("point coordinates: ({}, {})", point.x, point.y);
  32. // 使用結構體更新語法建立新的 point,這樣可以用到之前的 point 的欄位
  33. let new_point = Point { x: 0.1, ..point };
  34. // `new_point.y` 與 `point.y` 一樣,因為這個欄位就是從 `point` 中來的
  35. println!("second point: ({}, {})", new_point.x, new_point.y);
  36. // 使用 `let` 繫結來解構 point
  37. let Point { x: my_x, y: my_y } = point;
  38. let _rectangle = Rectangle {
  39. // 結構體的例項化也是一個表示式
  40. p1: Point { x: my_y, y: my_x },
  41. p2: point,
  42. };
  43. // 例項化一個單元結構體
  44. let _nil = Nil;
  45. // 例項化一個元組結構體
  46. let pair = Pair(1, 0.1);
  47. // 訪問元組結構體的欄位
  48. println!("pair contains {:?} and {:?}", pair.0, pair.1);
  49. // 解構一個元組結構體
  50. let Pair(integer, decimal) = pair;
  51. println!("pair contains {:?} and {:?}", integer, decimal);
  52. }

二、列舉

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

  1. //一個代表東南西北四個方向的列舉
  2. enum Direction {
  3. West,
  4. North,
  5. Sourth,
  6. East,
  7. }

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

  1. enum SpecialPoint {
  2. Point {
  3. x: i32,
  4. y: i32,
  5. },
  6. Special(String),
  7. }

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

樣例:

  1. // 該屬性用於隱藏對未使用程式碼的警告。
  2. #![allow(dead_code)]
  3. // 建立一個 `enum`(列舉)來對 web 事件分類。注意變數名和型別共同指定了 `enum`
  4. // 取值的種類:`PageLoad` 不等於 `PageUnload`,`KeyPress(char)` 不等於
  5. // `Paste(String)`。各個取值不同,互相獨立。
  6. enum WebEvent {
  7. // 一個 `enum` 可以是單元結構體(稱為 `unit-like` 或 `unit`),
  8. PageLoad,
  9. PageUnload,
  10. // 或者一個元組結構體,
  11. KeyPress(char),
  12. Paste(String),
  13. // 或者一個普通的結構體。
  14. Click { x: i64, y: i64 }
  15. }
  16. // 此函式將一個 `WebEvent` enum 作為引數,無返回值。
  17. fn inspect(event: WebEvent) {
  18. match event {
  19. WebEvent::PageLoad => println!("page loaded"),
  20. WebEvent::PageUnload => println!("page unloaded"),
  21. // 從 `enum` 裡解構出 `c`。
  22. WebEvent::KeyPress(c) => println!("pressed '{}'.", c),
  23. WebEvent::Paste(s) => println!("pasted \"{}\".", s),
  24. // 把 `Click` 解構給 `x` and `y`。
  25. WebEvent::Click { x, y } => {
  26. println!("clicked at x={}, y={}.", x, y);
  27. },
  28. }
  29. }
  30. fn main() {
  31. let pressed = WebEvent::KeyPress('x');
  32. // `to_owned()` 從一個字串切片中建立一個具有所有權的 `String`。
  33. let pasted = WebEvent::Paste("my text".to_owned());
  34. let click = WebEvent::Click { x: 20, y: 80 };
  35. let load = WebEvent::PageLoad;
  36. let unload = WebEvent::PageUnload;
  37. inspect(pressed);
  38. inspect(pasted);
  39. inspect(click);
  40. inspect(load);
  41. inspect(unload);
  42. }

其它

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

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

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