集册 Rust 中文教程 结构体与枚举

结构体与枚举

欢马劈雪     最近更新时间:2020-08-04 05:37:59

364

结构体

结构体 (struct) 是一种记录类型,所包含的每个域 (field) 都有一个名称。 每个结构体也都有一个名称,通常以大写字母开头,使用驼峰命名法。 元组结构体 (tuple struct) 是由元组和结构体混合构成,元组结构体有名称, 但是它的域没有。当元组结构体只有一个域时,称为新类型 (newtype)。 没有任何域的结构体,称为类单元结构体 (unit-like struct)。 结构体中的值默认是不可变的,需要给结构体加上mut使其可变。

// structs
struct Point {
  x: i32,
  y: i32,
}
let point = Point { x: 0, y: 0 };

// tuple structs
struct Color(u8, u8, u8);
let android_green = Color(0xa4, 0xc6, 0x39);
let Color(red, green, blue) = android_green;

// A tuple struct’s constructors can be used as functions.
struct Digit(i32);
let v = vec![0, 1, 2];
let d: Vec<Digit> = v.into_iter().map(Digit).collect();

// newtype: a tuple struct with only one element
struct Inches(i32);
let length = Inches(10);
let Inches(integer_length) = length;

// unit-like structs
struct EmptyStruct;
let empty = EmptyStruct;

一个包含..struct可以用来从其它结构体拷贝一些值或者在解构时忽略一些域:

#[derive(Default)]
struct Point3d {
    x: i32,
    y: i32,
    z: i32,
}

let origin = Point3d::default();
let point = Point3d { y: 1, ..origin };
let Point3d { x: x0, y: y0, .. } = point;

需要注意,Rust在语言级别不支持域可变性 (field mutability),所以不能这么写:

struct Point {
    mut x: i32,
    y: i32,
}

这是因为可变性是绑定的一个属性,而不是结构体自身的。可以使用Cell<T>来模拟:

use std::cell::Cell;

struct Point {
    x: i32,
    y: Cell<i32>,
}

let point = Point { x: 5, y: Cell::new(6) };

point.y.set(7);

此外,结构体的域对其所在模块 (mod) 之外默认是私有的,可以使用pub关键字将其设置成公开。

mod graph {
    #[derive(Default)]
    pub struct Point {
        pub x: i32,
        y: i32,
    }

    pub fn inside_fn() {
        let p = Point {x:1, y:2};
        println!("{}, {}", p.x, p.y);
    }
}

fn outside_fn() {
    let p = graph::Point::default();
    println!("{}", p.x);
    // println!("{}", p.y);
    // field `y` of struct `graph::Point` is private
}

枚举

Rust有一个集合类型,称为枚举 (enum),代表一系列子数据类型的集合。 其中子数据结构可以为空-如果全部子数据结构都是空的,就等价于C语言中的enum。 我们需要使用::来获得每个元素的名称。

展开阅读全文