主要使用如下两个关键字:

  • struct: 定义一个结构体(structure)
  • enum: 定义一个枚举类型(enumeration)

常量可以通过 conststatic 关键字来创建。

结构体

structure 有 3 种类型:

  • 元组结构体(tuple struct)。
  • 经典 C 语言风格(C struct)。
  • 单元结构体(unit struct),不带字段,在泛型中很有用。 ```rust

    [derive(Debug)]

    struct Person<’a> { name: &’a str, age: u8, }

// 单元结构体 struct Nil;

// 元组结构体 struct Pair(i32, f32);

fn main() { // 使用简单的写法初始化字段,并创建结构体 let name = “Peter”; let age = 27; let peter = Person { name, age };

  1. // 实例化结构体 `Point`
  2. let tom = Person {name: "tom", age: 3 };
  3. println!("person1:{:?}, {} is {}", peter, tom.name, tom.age);
  4. // 使用结构体更新语法创建新结构体,这样可以用到之前结构体的字段
  5. let jerry = Person { name: "jerry", ..tom };
  6. // 使用 `let` 绑定来解构 jerry
  7. let Person { name: jerry_name, age: jerry_age } = jerry;
  8. println!("{} is {}.", jerry_name, jerry_age);
  9. // 实例化一个单元结构体
  10. let _nil = Nil;
  11. // 实例化一个元组结构体
  12. let pair = Pair(1, 0.1);
  13. // 访问元组结构体的字段
  14. println!("pair contains {:?} and {:?}", pair.0, pair.1);
  15. // 解构一个元组结构体
  16. let Pair(integer, decimal) = pair;
  17. println!("pair contains {:?} and {:?}", integer, decimal);

}

  1. <a name="WOlsz"></a>
  2. # 枚举
  3. `enum` 关键字可以创建枚举类型(enumeration),该类型的实例只能在数个可能的取值中 取一种。任何一个合法的 `struct` 同时也是合法的 `enum` 取值。
  4. ```rust
  5. enum WebEvent {
  6. // 一个 `enum` 可以是单元结构体(称为 `unit-like` 或 `unit`),
  7. PageLoad,
  8. PageUnload,
  9. // 或者一个元组结构体,
  10. KeyPress(char),
  11. Paste(String),
  12. // 或者一个普通的结构体。
  13. Click { x: i64, y: i64 }
  14. }

类型别名

若使用类型别名,则可以通过其别名引用每个枚举变量。

  1. enum VeryVerboseEnumOfThingsToDoWithNumbers {
  2. Add,
  3. Subtract,
  4. }
  5. // Creates a type alias
  6. type Operations = VeryVerboseEnumOfThingsToDoWithNumbers;
  7. fn main() {
  8. // We can refer to each variant via its alias, not its long and inconvenient
  9. // name.
  10. let x = Operations::Add;
  11. }

常见用途, impl 块中的使用的 Self 别名。

使用 use

使用 use 声明以后就不需要写出名称的完整路径了。

  1. #![allow(dead_code)]
  2. enum Status {
  3. Rich,
  4. Poor,
  5. }
  6. enum Work {
  7. Civilian,
  8. Soldier,
  9. }
  10. fn main() {
  11. // 显式地 `use` 各个名称使他们直接可用,而不需要指定它们来自 `Status`。
  12. use Status::{Poor, Rich};
  13. // 自动地 `use` `Work` 内部的各个名称。
  14. use Work::*;
  15. }

C 风格用法

  1. // 拥有隐式辨别值(implicit discriminator,从 0 开始)的 enum
  2. enum Number {
  3. Zero,
  4. One,
  5. }
  6. // 拥有显式辨别值(explicit discriminator)的 enum
  7. enum Color {
  8. Red = 0xff0000,
  9. Green = 0x00ff00,
  10. }
  11. fn main() {
  12. // `enum` 可以转成整形。
  13. println!("zero is {}", Number::Zero as i32);
  14. println!("one is {}", Number::One as i32);
  15. println!("roses are #{:06x}", Color::Red as i32);
  16. }

链表(linked-list)

  1. use List::*;
  2. enum List {
  3. // Cons:元组结构体,包含链表的一个元素和一个指向下一节点的指针
  4. Cons(u32, Box<List>),
  5. // Nil:末结点,表明链表结束
  6. Nil,
  7. }
  8. // 可以为 enum 定义方法
  9. impl List {
  10. // 创建一个空的 List 实例
  11. fn new() -> List {
  12. // `Nil` 为 `List` 类型(译注:因 `Nil` 的完整名称是 `List::Nil`)
  13. Nil
  14. }
  15. // 处理一个 List,在其头部插入新元素,并返回该 List
  16. fn prepend(self, elem: u32) -> List {
  17. // `Cons` 同样为 List 类型
  18. Cons(elem, Box::new(self))
  19. }
  20. // 返回 List 的长度
  21. fn len(&self) -> u32 {
  22. // 必须对 `self` 进行匹配(match),因为这个方法的行为取决于 `self` 的
  23. // 取值种类。
  24. // `self` 为 `&List` 类型,`*self` 为 `List` 类型,匹配一个具体的 `T`
  25. // 类型要好过匹配引用 `&T`。
  26. match *self {
  27. // 不能得到 tail 的所有权,因为 `self` 是借用的;
  28. // 因此使用一个对 tail 的引用
  29. Cons(_, ref tail) => 1 + tail.len(),
  30. // (递归的)基准情形(base case):一个长度为 0 的空列表
  31. Nil => 0
  32. }
  33. }
  34. // 返回列表的字符串表示(该字符串是堆分配的)
  35. fn stringify(&self) -> String {
  36. match *self {
  37. Cons(head, ref tail) => {
  38. // `format!` 和 `print!` 类似,但返回的是一个堆分配的字符串,
  39. // 而不是打印结果到控制台上
  40. format!("{}, {}", head, tail.stringify())
  41. },
  42. Nil => {
  43. format!("Nil")
  44. },
  45. }
  46. }
  47. }
  48. fn main() {
  49. // 创建一个空链表
  50. let mut list = List::new();
  51. // 追加一些元素
  52. list = list.prepend(1);
  53. list = list.prepend(2);
  54. list = list.prepend(3);
  55. // 显示链表的最后状态
  56. println!("linked list has length: {}", list.len());
  57. println!("{}", list.stringify());
  58. }

常量

包含两种常量,可以在任意作用域声明,包含全局作用域。都需要显示的类型声明:

  • const:不可改变的值(通常使用这种)。
  • static:具有 'static 生命周期的,可以是可变的变量(译注:须使用 static mut 关键字)。
    1. const MAX: i32 = 1000;
    2. // 全局变量是在在所有其他作用域之外声明的。
    3. static LANGUAGE: &'static str = "Rust";
    4. static mut THRESHOLD: i32 = 10; // 可变常量
    有个特例就是 "string" 字面量。它可以不经改动就被赋给一个 static 变量,因为它 的类型标记:&'static str 就包含了所要求的生命周期 'static。其他的引用类型都 必须特地声明,使之拥有'static 生命周期。这两种引用类型的差异似乎也无关紧要,因 为无论如何,static 变量都得显式地声明。