主要使用如下两个关键字:
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` 绑定来解构 jerry
let 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` 取值。
```rust
enum WebEvent {
// 一个 `enum` 可以是单元结构体(称为 `unit-like` 或 `unit`),
PageLoad,
PageUnload,
// 或者一个元组结构体,
KeyPress(char),
Paste(String),
// 或者一个普通的结构体。
Click { x: i64, y: i64 }
}
类型别名
若使用类型别名,则可以通过其别名引用每个枚举变量。
enum VeryVerboseEnumOfThingsToDoWithNumbers {
Add,
Subtract,
}
// Creates a type alias
type 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 开始)的 enum
enum Number {
Zero,
One,
}
// 拥有显式辨别值(explicit discriminator)的 enum
enum 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,在其头部插入新元素,并返回该 List
fn 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
变量都得显式地声明。