Rust自定义类型

一、自定义类型
自定义数据类型主要有:结构体、枚举

  1. 结构体:通过struct关键字创建。
  2. 枚举:通过enum关键字创建。

1.1 结构体
结构体与元组类似,也可以把多个类型组合到一起,作为新的类型。区别在于,它的每个元素都有自己的名字。
结构体中每个元素之间采用逗号分开,最后一个逗号可以省略不写。类型跟在冒号后面,但是不能使用自动类型推导功能,必须显式指定。结构体类型的初始化语法类似于json的语法,使用“成员–冒号–值”的格式。如果有局部变量名字和成员变量名字恰好一致,那么可以省略掉重复的冒号初始化,这是一种简化的写法。

结构体有三种类型:普通结构体、元组结构体、单元结构体

  1. 普通结构体:与经典的C语言风格结构体类似。
  2. 元组结构体:事实上就是具名元组而已。它就像是元组和结构体的混合。区别在于,元组结构体有名字,而它的成员没有名字。
  3. 单元结构体:不带字段的结构体。

以下是简单的样例:

#[derive(Debug)]
struct Person {
    name: String,
    age: u8,
}

//单元结构体
struct Unit;

//元组结构体
struct Pair(i32, f32);

//普通结构体
struct Point {
    x: f32,
    y: f32,
}

//结构体可以作为另一个结构体的字段
#[allow(dead_code)]
struct Rectangle {
    top_left: Point,
    bottom_right: Point,
}

fn main() {
    //局部变量名字和成员变量名字恰好一致,使用简化写法
    let name = String::from("Peter");
    let age = 27;
    let peter = Person { name, age };

    //使用了Debug属性的结构体,可以用Debug方式打印结构体
    println!("{:?}", peter);

    //实例化结构体Point
    let point: Point = Point { x: 10.3, y: 0.4 };

    //访问point的字段
    println!("point coordinates: ({}, {})", point.x, point.y);

    //使用结构体更新语法创建新的point,
    //这样可以用到之前的point的字段
    let bottom_right = Point { x: 5.2, ..point };

    //bottom_right.y与point.y一样,因为这个字段就是从point中来的
    println!("second point: ({}, {})", bottom_right.x, bottom_right.y);

    //使用let绑定来解构point
    let Point {
        x: left_edge,
        y: top_edge,
    } = point;

    let _rectangle = Rectangle {
        //结构体的实例化也是一个表达式
        top_left: Point {
            x: left_edge,
            y: top_edge,
        },
        bottom_right: bottom_right,
    };

    //实例化一个单元结构体
    let _unit = Unit;

    //实例化一个元组结构体
    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);
}

1.2 枚举
枚举类型允许创建一个从数个不同取值中选其一。Rust枚举类型也可以像C语言风格的枚举类型那样使用。与C/C++中的枚举相比,Rust中的枚举要强大得多,它可以为每个成员指定附属的类型信息。枚举中的每个元素的定义语法与结构体的定义语法类似,任何一个在 结构体中合法的取值在枚举中也合法。
枚举和结构体为内部成员创建了新的名字空间。如果要访问内部成员,可以使用::符号。因此,不同的枚举中重名的元素也不会互相冲突。
在没有重名的元素的情况下,使用use声明,就可以不写出名称的完整路径了,但是如果存在重名的元素,则需要名称的完整路径。

以下是简单的样例:

//该属性用于隐藏对未使用代码的警告。
#![allow(dead_code)]

enum Status {
    Rich,
    Poor,
}

enum Work {
    Civilian,
    Soldier,
}

//C语言风格枚举,拥有隐式辨别值,从0开始的
enum Number {
    Zero,
    One,
    Two,
}

//C语言风格枚举,拥有显式辨别值
enum Color {
    Red = 0xff0000,
    Green = 0x00ff00,
    Blue = 0x0000ff,
}

fn main() {
    //显式地use各个名称使他们直接可用,而不需要指定它们来自Status
    use Status::{Poor, Rich};
    //自动地use Work内部的各个名称
    use Work::*;

    //Poor等价于Status::Poor
    let status = Poor;
    //Civilian等价于Work::Civilian
    let work = Civilian;

    //使用模式匹配
    match status {
        //没有用完整路径,因为上面显式地使用了use
        Rich => println!("The rich have lots of money!"),
        Poor => println!("The poor have no money..."),
    }

    //使用模式匹配
    match work {
        //没有用完整路径,因为上面显式地使用了use
        Civilian => println!("Civilians work!"),
        Soldier => println!("Soldiers fight!"),
    }

    //枚举成员值可以转成整型
    println!("zero is {}", Number::Zero as i32);
    println!("one is {}", Number::One as i32);

    println!("roses are #{:06x}", Color::Red as i32);
    println!("violets are #{:06x}", Color::Blue as i32);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值