主要使用如下两个关键字:
struct: 定义一个结构体(structure)enum: 定义一个枚举类型(enumeration)
常量可以通过 const 和 static 关键字来创建。
结构体
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 };
// 实例化结构体 `Point`let tom = Person {name: "tom", age: 3 };println!("person1:{:?}, {} is {}", peter, tom.name, tom.age);// 使用结构体更新语法创建新结构体,这样可以用到之前结构体的字段let jerry = Person { name: "jerry", ..tom };// 使用 `let` 绑定来解构 jerrylet Person { name: jerry_name, age: jerry_age } = jerry;println!("{} is {}.", jerry_name, jerry_age);// 实例化一个单元结构体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);
}
<a name="WOlsz"></a># 枚举`enum` 关键字可以创建枚举类型(enumeration),该类型的实例只能在数个可能的取值中 取一种。任何一个合法的 `struct` 同时也是合法的 `enum` 取值。```rustenum WebEvent {// 一个 `enum` 可以是单元结构体(称为 `unit-like` 或 `unit`),PageLoad,PageUnload,// 或者一个元组结构体,KeyPress(char),Paste(String),// 或者一个普通的结构体。Click { x: i64, y: i64 }}
类型别名
若使用类型别名,则可以通过其别名引用每个枚举变量。
enum VeryVerboseEnumOfThingsToDoWithNumbers {Add,Subtract,}// Creates a type aliastype Operations = VeryVerboseEnumOfThingsToDoWithNumbers;fn main() {// We can refer to each variant via its alias, not its long and inconvenient// name.let x = Operations::Add;}
使用 use
使用 use 声明以后就不需要写出名称的完整路径了。
#![allow(dead_code)]enum Status {Rich,Poor,}enum Work {Civilian,Soldier,}fn main() {// 显式地 `use` 各个名称使他们直接可用,而不需要指定它们来自 `Status`。use Status::{Poor, Rich};// 自动地 `use` `Work` 内部的各个名称。use Work::*;}
C 风格用法
// 拥有隐式辨别值(implicit discriminator,从 0 开始)的 enumenum Number {Zero,One,}// 拥有显式辨别值(explicit discriminator)的 enumenum Color {Red = 0xff0000,Green = 0x00ff00,}fn main() {// `enum` 可以转成整形。println!("zero is {}", Number::Zero as i32);println!("one is {}", Number::One as i32);println!("roses are #{:06x}", Color::Red as i32);}
链表(linked-list)
use List::*;enum List {// Cons:元组结构体,包含链表的一个元素和一个指向下一节点的指针Cons(u32, Box<List>),// Nil:末结点,表明链表结束Nil,}// 可以为 enum 定义方法impl List {// 创建一个空的 List 实例fn new() -> List {// `Nil` 为 `List` 类型(译注:因 `Nil` 的完整名称是 `List::Nil`)Nil}// 处理一个 List,在其头部插入新元素,并返回该 Listfn prepend(self, elem: u32) -> List {// `Cons` 同样为 List 类型Cons(elem, Box::new(self))}// 返回 List 的长度fn len(&self) -> u32 {// 必须对 `self` 进行匹配(match),因为这个方法的行为取决于 `self` 的// 取值种类。// `self` 为 `&List` 类型,`*self` 为 `List` 类型,匹配一个具体的 `T`// 类型要好过匹配引用 `&T`。match *self {// 不能得到 tail 的所有权,因为 `self` 是借用的;// 因此使用一个对 tail 的引用Cons(_, ref tail) => 1 + tail.len(),// (递归的)基准情形(base case):一个长度为 0 的空列表Nil => 0}}// 返回列表的字符串表示(该字符串是堆分配的)fn stringify(&self) -> String {match *self {Cons(head, ref tail) => {// `format!` 和 `print!` 类似,但返回的是一个堆分配的字符串,// 而不是打印结果到控制台上format!("{}, {}", head, tail.stringify())},Nil => {format!("Nil")},}}}fn main() {// 创建一个空链表let mut list = List::new();// 追加一些元素list = list.prepend(1);list = list.prepend(2);list = list.prepend(3);// 显示链表的最后状态println!("linked list has length: {}", list.len());println!("{}", list.stringify());}
常量
包含两种常量,可以在任意作用域声明,包含全局作用域。都需要显示的类型声明:
const:不可改变的值(通常使用这种)。static:具有'static生命周期的,可以是可变的变量(译注:须使用static mut关键字)。
有个特例就是const MAX: i32 = 1000;// 全局变量是在在所有其他作用域之外声明的。static LANGUAGE: &'static str = "Rust";static mut THRESHOLD: i32 = 10; // 可变常量
"string"字面量。它可以不经改动就被赋给一个static变量,因为它 的类型标记:&'static str就包含了所要求的生命周期'static。其他的引用类型都 必须特地声明,使之拥有'static生命周期。这两种引用类型的差异似乎也无关紧要,因 为无论如何,static变量都得显式地声明。
