30天拿下Rust之枚举

03-08 1671阅读 0评论

概述

        Rust中的枚举是一种用户定义的类型,它允许你为一组相关的值赋予友好的名称。在Rust中,枚举是强大的工具,它们不仅仅用于表示几个固定的值,还可以包含函数和方法,使得枚举成员可以有自己的行为。通过与模式匹配和其他Rust特性结合使用,枚举在构建健壮、无崩溃的应用程序中发挥了重要作用,并可大幅提高代码的可读性、可维护性和类型安全性。

30天拿下Rust之枚举,30天拿下Rust之枚举,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,使用,我们,访问,第1张
(图片来源网络,侵删)

基础枚举

        在Rust中,枚举通过关键字enum进行声明,它可以包含一组相关的命名常量。比如:我们可以定义一个枚举来表示一周的几天。

enum Day {
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    Sunday,
}

        定义好枚举后,我们可以像下面这样使用枚举值。

let cur_day = Day::Wednesday;

关联枚举

        Rust中的枚举还可以带有关联值,这使得枚举成员可以有不同的数据类型。比如:我们可以定义一个表示结果的枚举,其中一个成员包含整数值,另一个成员则包含字符串值。

enum Result {
    Ok(i32),
    Err(String),
}
fn main() {
    let success = Result::Ok(66);
    let failure = Result::Err(String::from("failed"));
}

        在上面的示例代码中,Result::Ok有一个i32类型的关联值,Result::Err有一个String类型的关联值。

        另外,我们还可以为枚举中的属性命名,类似于结构体的语法。但请特别注意:枚举并不能像访问结构体字段那样访问枚举绑定的属性,访问的方法可参考下面的匹配枚举。

enum Shape {
    Point {x: i32, y: i32},
    Rectangle {width: i32, height: i32},
    Circle(i32),
}
fn main() {
    let point = Shape::Point{x: 66, y: 88};
    let rect = Shape::Rectangle{width: 10, height: 20};
    let circle = Shape::Circle(100);
}

匹配枚举

        使用match表达式,可以很方便地处理枚举类型的值。Rust强制要求枚举的所有可能变体在match表达式中都被考虑到,以避免未处理的枚举导致的运行时错误。

30天拿下Rust之枚举,30天拿下Rust之枚举,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,使用,我们,访问,第2张
(图片来源网络,侵删)
enum Direction {
    Up(u32),
    Down(i32),
    Left(String),
    Right(String),
}
fn main() {
    let direction = Direction::Up(66);
    match direction {
        Direction::Up(value) => println!("turn up by {}", value),
        Direction::Down(value) => println!("turn down by {}", value),
        Direction::Left(text) => println!("turn left to {}", text),
        Direction::Right(text) => println!("turn right to {}", text),
    }
}

        match表达式也可以当作函数表达式来对待,它是可以有返回值的。但有一点需要注意:所有返回值表达式的类型必须一样。

enum Direction {
    Up(u32),
    Down(i32),
    Left(String),
    Right(String),
}
fn convert(direction: Direction) -> u32 {
    match direction {
        Direction::Up(value) => 100,
        Direction::Down(value) => 200,
        Direction::Left(text) => 300,
        Direction::Right(text) => 400,
    }
}
fn main() {
    let value = convert(Direction::Down(99));
    println!("{}", value);
}

        在match表达式中,还可以使用通配符,用于对一些特定的值采取特殊操作,而对其他的值采取默认操作。在下面的示例代码中,我们对88和99采取了特殊操作,但对其他值采取了统一的默认处理。

fn main() {
    let value = 66;
    match value {
        88 => println!("conditon 88"),
        99 => println!("conditon 99"),
        other => println!("other conditon {}", other),
    }
}

        注意:我们必须将通配分支放在最后,因为模式是按顺序匹配的。如果我们在通配分支后再添加其他分支,Rust在编译时会警告我们“unreachable pattern”,因为此后的分支永远不会被匹配到。

        另外,Rust还提供了一种模式:当我们不想使用通配模式获取的值时,可以使用占位符_。这是一种特殊的模式,可以匹配任意值而不绑定到该值。占位符会告诉Rust,我们不会使用这个值,因此Rust也不会警告我们存在未使用的变量。

fn main() {
    let value = 66;
    match value {
        88 => println!("conditon 88"),
        99 => println!("conditon 99"),
        _ => println!("other conditons"),
    }
}

        可以看到,对于只有两种匹配情况的场景来说,match显得比较繁琐,必须使用通配符或占位符。为此,Rust提供了语法糖if let,用于简化代码。可以在if let中包含一个else,else块中的代码与match表达式中占位符分支块中的代码相同。

fn main() {
    let value = 66;
    if let 66 = value {
        println!("conditon 66");
    } else {
        println!("other conditons");
    }
}

        使用if let,意味着编写更少的代码,但这会失去match强制要求的穷尽性检查(因为else是可选的)。到底该使用match还是if let,取决于我们对增加简洁度和失去穷尽性检查之间的权衡取舍。

30天拿下Rust之枚举,30天拿下Rust之枚举,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,使用,我们,访问,第3张
(图片来源网络,侵删)

Option枚举

        Rust中的Option类型是一种枚举,它是Rust语言的核心特性之一,用于处理值可能存在的状态。在许多其他编程语言中,这种场景可能会使用null、None或其他表示空或缺失的特殊值来处理,但这些通常会导致潜在的空引用错误。而Rust通过设计Option类型,强制开发者在编译时就必须考虑值可能不存在的情况,从而保证了运行时的安全性。

        Option类型的定义如下:

pub enum Option {
    None,
    Some(T),
}

        Option中,T是一个泛型参数,代表了当值存在时的具体类型。这意味着,Option可以包裹任何类型的值。比如:Option表示可能包含一个整数值,或者没有值。

        Option类型提供的主要方法如下。

        unwrap(): 如果Option是Some(value),则返回该value;如果Option是None,则触发异常。这主要用于开发阶段调试和确定程序逻辑正确的地方,不推荐在生产代码中滥用,因为它会直接终止程序执行。

        expect(msg): 类似于unwrap(), 但在触发异常时,提供了一个自定义的消息。

        is_none(): 返回一个布尔值,表示Option是否为None。

        is_some(): 返回一个布尔值,表示Option是否有值。

        ok_or(err): 将Option转换成Result,若为Some则映射到Ok(_),若为None则映射到Err(err)。

        map(f): 如果Option是Some(T),应用函数f给T并返回一个新的Option


免责声明
本网站所收集的部分公开资料来源于AI生成和互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

发表评论

快捷回复: 表情:
评论列表 (暂无评论,1671人围观)

还没有评论,来说两句吧...

目录[+]