本期文章接上期继续讲述Rust语言中的数据类型,Rust自定义数据类型主要是通过下面这两个关键字来创建:
- 结构体( struct ): 定义一个结构体(structure)
- 枚举( enum ): 定义一个枚举类型(enumeration)
其余的类型常量则可以通过 const 和 static 来创建。
一、结构体
结构体有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