Rust 复合数据类型
- 元组 tuple
- 结构体 sturct
- 枚举体 enum
- 联合体 union
元组
元素是异构的有限序列,形如 (A, B, G)。
- 异构:元组的内部元素类型可以各不相同
- 有限:元素的内部元素数量是固定有限的
- () 是 空元组
- 元组可以使用 索引 来访问内部元素
- let支持模式匹配,可以使用 模式匹配 来解构元组的内部元素
fn main() {
let t1: (&str, i32, char) = ("hello", 5, 'c');
// 可以使用索引来访问元组的元素, 输出: t1.0 = hello, t1.1 = 5, t1.2 = c
println!("t1.0 = {}, t1.1 = {}, t1.2 = {}", t1.0, t1.1, t1.2);
// 直接把元组赋值给变量,然后索引访问
let x = (3.5, 6.3);
let y = add_one(x);
println!("y.0 = {}, y.1 = {}", y.0, y.1); // 输出: y.0 = 4.5, y.1 = 7.3
// let 支持模式匹配,可以用来解构元组。
let (a, b) = add_one(y);
println!("a = {}, b = {}", a, b); // 输出: a = 5.5, b = 8.3
}
fn add_one(x: (f64, f64)) -> (f64, f64) {
(x.0 + 1.0, x.1 + 1.0)
}
结构体
Rust 提供三种结构体类型:
- 具名结构体 (Named-Field Struct)
- 元组结构体 (Tuple-Like Struct)
- 单元结构体 (Unit-Like Struct)
具名结构体
fn main() {
let xm = Student {
name: "xiaoming",
age: 13,
};
xm.name();
xm.age();
let mut xw = Student::new("xiaowang", 12);
xw.name();
xw.age();
xw.set_name("wangming");
xw.name();
}
#[derive(Debug, PartialEq, Eq)]
struct Student {
name: &'static str,
age: i32,
}
impl Student {
fn new(name: &'static str, age: i32) -> Student {
Student { name, age }
}
fn name(&self) -> &str {
println!("student name: {}", self.name);
&self.name
}
fn set_name(&mut self, name: &'static str) {
self.name = name;
}
fn age(&self) -> i32 {
println!("student age: {}", self.age);
self.age
}
}
- 具名结构体是面向对象思想的体现;
- impl 实现的函数是 关联函数,关联了对应的 结构体类型。关联函数包括:
- 成员方法:首个参数是 &self 或 &mut self 的方法。使用 obj. 方式调用。
- 静态方法:无 &self / &mut self 参数的方法。使用 struct:: 方式调用。
- 于关联函数对应的是 自由函数,即 不在 impl 块中定义的函数。
元组结构体
- 元组结构体的字段没有名称,只有类型
- 元组结构体 通过 .idx 来访问相应位置的元素。
fn main() {
let color1: Color = Color(126, 204, 130);
println!("color1: {}, {}, {}", color1.0, color1.1, color1.2);
println!("color1 = {:?}", color1);
}
#[derive(Debug)]
struct Color(i32, i32, i32);
- 当一个元组结构体,只有一个字段的时候,称之为 New Type 模式。
- New Type 的意思是说 把一个类型 包装成了 另一个类型。
struct Integer(u8);
type Int = u8;
fn main() {
let int1 = Integer(12);
assert_eq!(int1.0, 12);
let int2: Int = 16;
assert_eq!(int2, 16);
assert_eq!(int1.0, int2 - 4);
}
单元结构体
- 单元结构体是 没有任何字段 的结构体。
- 单元结构体一般用于一些特定场景。 // 哪些场景呢?
struct Empty;
fn main() {
let x = Empty;
println!("x = {:p}", &x);
let y = x;
println!("y = {:p}", &y);
let z = Empty;
println!("z = {:p}", &z);
assert_eq!((..), std::ops::RangeFull);
}
枚举体
- 枚举体有三种类型:(1) 无参枚举体; (2) 类 C 枚举体;(3) 带参枚举体
- 该类型包含了各种可能的情况,防止用户传递无效的参数
无参枚举体
// 这里的 Zero, One, Two, Three 是枚举类型 Number 的四个值,而不是类型。
enum Number {
Zero,
One,
Two,
Three,
}
fn main() {
let a = Number::Three;
match a {
Number::Zero => println!("0"),
Number::One => println!("1"),
Number::Two => println!("2"),
_ => println!("more than 2"),
}
}
类 C 枚举体
- 每个枚举值都有一个对应 isize 类型的值。可以被 as 转换为所有 isize 可以转化的值。
enum Color {
Red = 0xff0000,
Green = 0x00ff00,
Blue = 0x0000ff,
}
fn main() {
println!("red is: {}", Color::Red as i32); // red is: 16711680
println!("blue is: {}", Color::Blue as i32); // blue is: 255
}
带参数枚举体
- 最常用的有 Option 枚举体,包括 Some<T> 和 None 两个值。
fn main() {
// let s = Option::Some((10, 1.6));
let s: Option<(i32, f64)> = Some((10, 1.6));
// unwrap 是 Option 的一个成员方法,如果值是 None,则 panic
let num = s.unwrap();
println!("num = {:?}", num);
match s {
Some(a) => println!("a = {:?}", a),
None => (),
}
}