当前位置: 首页 > news >正文

Rust学习总结之-枚举

枚举是一个很多语言都有的功能,不过不同语言中其功能各不相同但是要表达的意思是一致的,枚举就是对于一个事物可以穷举出所有可能得值。比如说人的性别就可以用枚举,男人和女人两种。下面我们来学习Rust中的枚举。

一:枚举定义

定义一个IP地址的枚举,对于IP地址目前广泛使用的有两种,IPV4和IPV6。任何一个 IP 地址要么是 IPv4 的要么是 IPv6 的,而且不能两者都是。IP 地址的这个特性使得枚举数据结构非常适合这个场景,因为枚举值只可能是其中一个成员。IPv4 和 IPv6 从根本上讲仍是 IP 地址,所以当代码在处理适用于任何类型的 IP 地址的场景时应该把它们当作相同的类型。

enum IpAddrKind {
    V4,
    V6,
}

定义一个 IpAddrKind 枚举来表现这个概念并列出可能的 IP 地址类型,V4 和 V6

二:枚举值使用

创建 IpAddrKind 两个不同成员的实例:

let four = IpAddrKind::V4;
let six = IpAddrKind::V6;

函数入参为枚举类型

fn route(ip_type: IpAddrKind) { }

调用上面的route函数

route(IpAddrKind::V4);
route(IpAddrKind::V6);

 我们定义一个结构体,里面有个两个成员,一是指示IP类型,二是定义IP地址

enum IpAddrKind {
    V4,
    V6,
}

struct IpAddr {
    kind: IpAddrKind,
    address: String,
}

fn main() {
    let home = IpAddr {
        kind: IpAddrKind::V4,
        address: String::from("127.0.0.1"),
    };
    
    let loopback = IpAddr {
        kind: IpAddrKind::V6,
        address: String::from("::1"),
    };
    println!("home ip is {}",home.address);
    println!("loopback ip is {}",loopback.address);
}

运行结果

有告警,因为结构体kind没有使用

我们可以使用一种更简洁的方式来表达相同的概念,仅仅使用枚举并将数据直接放进每一个枚举成员而不是将枚举作为结构体的一部分。IpAddr 枚举的新定义表明了 V4 和 V6 成员都关联了 String 值:

#[derive(Debug)]
enum IpAddr {
    V4(String),
    V6(String),
}

fn main() {
    let home = IpAddr::V4(String::from("127.0.0.1"));

    let loopback = IpAddr::V6(String::from("::1"));
    println!("home ip is {:?}",home);
    println!("loopback ip is {:?}",loopback);
}

运行结果 

用枚举替代结构体还有另一个优势:每个成员可以处理不同类型和数量的数据。IPv4 版本的 IP 地址总是含有四个值在 0 和 255 之间的数字部分。如果我们想要将 V4 地址存储为四个 u8 值而 V6 地址仍然表现为一个 String

enum IpAddr {
    V4(u8, u8, u8, u8),
    V6(String),
}

let home = IpAddr::V4(127, 0, 0, 1);

let loopback = IpAddr::V6(String::from("::1"));

再看一个稍微复杂的枚举例子,它的成员中内嵌了多种多样的类型

enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(i32, i32, i32),
}

这个枚举有四个含有不同类型的成员:

  • Quit 没有关联任何数据。
  • Move 包含一个匿名结构体。
  • Write 包含单独一个 String
  • ChangeColor 包含三个 i32

枚举和结构体还有另一个相似点:就像可以使用 impl 来为结构体定义方法那样,也可以在枚举上定义方法。这是我们在 Message 枚举上定义了一个叫做 call 的方法:

impl Message {
    fn call(&self) {
        // 在这里定义方法体
    }
}

let m = Message::Write(String::from("hello"));
m.call();

相关文章:

  • 半导体晶圆精控:ethercat转profient网关数据提升制造精度
  • 2024中国信通院“集智”蓝皮书合集(附下载)
  • Windows-内核
  • 解决免费 PDF 发票打印痛点的实用工具
  • 回调函数的用法
  • AI大模型-提示工程学习笔记19-自我反思
  • HBuilder X安装教程(2025版)
  • C++ ⾼性能内存池
  • Spring 创建对象的流程
  • Rk3568驱动开发_点亮led灯(手动挡)_5
  • 文件上传漏洞学习笔记
  • 【SRC实战】搜索功能泄露订单号+用户定位
  • 自学c++之类、对象、封装
  • 【语法】C++的string
  • 解决应用程序 0xc00000142 错误:完整修复指南
  • 记录Liunx安装Jenkins时的Package ‘jenkins‘ has no installation candidate
  • 全星QMS软件系统:制造业质量管理的全面优化与创新研究
  • 开源基准测试模拟器:BlueROV2 水下机器人的控制(更改Z方向控制器)
  • JAVA面试常见题_基础部分_Dubbo面试题(上)
  • 2025/2/25,字节跳动后端开发一面面经
  • 五一假期首日,上海外滩客流超55万人次
  • 五一首日出沪高峰,G1503高东收费站上午车速约30公里/小时
  • 2025年第一批“闯中人”已经准备好了
  • 秦洪看盘|资金切换主线,重构市场风格
  • 中央网信办部署开展“清朗·整治AI技术滥用”专项行动
  • 深观察丨从“不建议将导师挂名为第一作者”说开去