Rust指南枚舉類與模式匹配詳解

前言
書接上文,本篇博客分享的是Rust 枚舉類與模式匹配 的知識。作為安全性強的語言,Rust 的枚舉類并不像其他編程語言中的概念那樣簡單,但依然可以十分簡單的使用。
1、Rust基本枚舉類語法
枚舉允許我們列舉所有可能的值來定義一個類型,枚舉中的值也叫變體
1.1、定義枚舉
我們舉一個例子:
IP地址:IPV4、IPV6
enum IpAddrKind{
V4,
V6
}接收枚舉值
let four=IpAddrKind::V4; let six=IpAddrKind::V6;
枚舉的變體都位于標識符的命名空間下,使用::進行分割
1.2、將數(shù)據(jù)附加到枚舉的變體中
形式如下:
enum IpAddr{
V4(String),
V6(String)
}優(yōu)點:
- 不需要額外使用
struct來確定類型 - 每個變體可以擁有不同的類型以及關(guān)聯(lián)的數(shù)據(jù)量
例如:
#[derive(Debug)]
enum IpAddrKind {
V4(u8,u8,u8,u8),
V6(String)
}
fn main() {
let home=IpAddrKind::V4(127, 0, 0, 1);
let loopback=IpAddrKind::V6(String::from("這是IPV6"));
println!("{:?}\n{:?}",home,loopback);
}
運行效果:

#[derive(Debug)]作為Rust提供的調(diào)試庫是可以直接輸出結(jié)構(gòu)體和枚舉類型的- 但是注意占位符只能使用
{:?} - 標準庫中的IpAddr
struct IpV4Addr{
//--snip--
}
struct IpV6Addr{
//--snip--
}
enum IpAddr {
V4(IpV4Addr),
V6(IpV6Addr)
}1.3、變體的多種嵌套方式
enum Message {
Quit,
Move {x:i32,y:u32},
Write(String),
ChangeColor(i32,i32,i32)
}
fn main() {
let q=Message::Quit;
let m=Message::Move { x: 6, y: 12 };
let w=Message::Write(String::from("hello_world"));
let c=Message::ChangeColor(255, 255, 0);
}
在這段代碼中枚舉類變體一共有四種數(shù)據(jù)類型:
- 不帶關(guān)聯(lián)數(shù)據(jù)
Quit - 匿名結(jié)構(gòu)體
Move - 字符串類型
Write - 匿名元組結(jié)構(gòu)體
ChangeColor
1.4、定義枚舉方法
和結(jié)構(gòu)體方法類似,使用impl關(guān)鍵字:
impl Message{
fn call(&self){}
}這里就不具體實現(xiàn)了,此時枚舉的所有變體都可以調(diào)用call方法,例如q.call();
2、Option枚舉
2.1、引入Option枚舉解決控制問題
Option是 Rust 標準庫中的枚舉類,這個類用于填補 Rust 不支持null引用的空白。- 許多語言支持 null 的存在(C/C++、Java),這樣很方便,但也制造了極大的問題,null 的發(fā)明者也承認這一點,“一個方便的想法造成累計 10 億美元的損失”。
null經(jīng)常在開發(fā)者把一切都當作不是 null 的時候給予程序致命一擊:畢竟只要出現(xiàn)一個這樣的錯誤,程序的運行就要徹底終止。- 為了解決這個問題,很多語言默認不允許 null,但在語言層面支持 null 的出現(xiàn)(常在類型前面用 ? 符號修飾)。
- Java 默認支持 null,但可以通過 @NotNull 注解限制出現(xiàn) null,這是一種應(yīng)付的辦法。
Rust 在語言層面徹底不允許空值 null 的存在,但無奈null 可以高效地解決少量的問題,所以 Rust 引入了 Option 枚舉類:
enum Option<T>{
Some(T),
None
}2.2、枚舉類的具體使用
枚舉類包含在預(yù)導(dǎo)入模塊中(Prelude),可直接使用:
let some_number=Some(5);
let some_string=Some("a string")
let absent:Option<&str>=None;注意:
- 編譯器無法推斷None是什么類型,所以一定要顯示聲明
- 由于
absent屬于None的變體,因此是無效數(shù)據(jù),也就是null
3、match控制流運算符
- 枚舉的目的是對某一類事物的分類,分類的目的是為了對不同的情況進行描述。
- 基于這個原理,往往枚舉類最終都會被分支結(jié)構(gòu)處理(許多語言中的 switch )。
- switch 語法很經(jīng)典,但在 Rust 中并不支持,很多語言摒棄 switch 的原因都是因為 switch 容易存在因忘記添加 break 而產(chǎn)生的串接運行問題,Java 和 C# 這類語言通過安全檢查杜絕這種情況出現(xiàn)。
Rust 通過 match 語句來實現(xiàn)分支結(jié)構(gòu)。先認識一下如何用 match 處理枚舉類:
fn main() {
enum Book {
Papery {index: u32},
Electronic {url: String},
}
let book = Book::Papery{index: 1001};
let ebook = Book::Electronic{url: String::from("url...")};
match book {
Book::Papery { index } => {
println!("Papery book {}", index);
},
Book::Electronic { url } => {
println!("E-book {}", url);
}
}
}
//運行結(jié)果:Papery book 1001
這是由于book屬于Papery的變體,因此會執(zhí)行第一個打印語句
match 塊也可以當作函數(shù)表達式來對待,它也是可以有返回值的:
match 枚舉類實例 {
分類1 => 返回值表達式,
分類2 => 返回值表達式,
...
}
但是要謹記:所有返回值表達式的類型必須一樣!
如果把枚舉類附加屬性定義成元組,在 match 塊中需要臨時指定一個名字:
enum Book {
Papery(u32),
Electronic {url: String},
}
let book = Book::Papery(1001);
match book {
Book::Papery(i) => {
println!("{}", i);
},
Book::Electronic { url } => {
println!("{}", url);
}
}
變體Papery指定了i變量,Electronic指定了url
match 除了能夠?qū)γ杜e類進行分支選擇以外,還可以對整數(shù)、浮點數(shù)、字符和字符串切片引用(&str)類型的數(shù)據(jù)進行分支選擇。其中,浮點數(shù)類型被分支選擇雖然合法,但不推薦這樣使用,因為精度問題可能會導(dǎo)致分支錯誤。
對非枚舉類進行分支選擇時必須注意處理例外情況,即使在例外情況下沒有任何要做的事。例外情況用下劃線 _ 表示:
fn main() {
let t = "abc";
match t {
"abc" => println!("Yes"),
_ => {},
}
}
4、if let 語法
通過一個簡單的流程控制代碼理解此部分知識:
let i = 0;
match i {
0 => println!("zero"),
_ => {},
}
//主函數(shù)中運行結(jié)果:zero
這段程序的目的是判斷 i 是否是數(shù)字 0,如果是就打印 zero。
那么現(xiàn)在用 if let 語法縮短這段代碼:
let i = 0;
if let 0 = i {
println!("zero");
}
if let 語法格式如下:
if let 匹配值 = 源變量 {
語句塊
}
- 可以在之后添加一個
else塊來處理例外情況。
if let 語法可以認為是只區(qū)分兩種情況的 match 語句的"語法糖"
在枚舉類中的使用:
fn main() {
enum Book {
Papery(u32),
Electronic(String)
}
let book = Book::Electronic(String::from("url"));
if let Book::Papery(index) = book {
println!("Papery {}", index);
} else {
println!("Not papery book");
}
}
//運行結(jié)果:Not papery bookRust 枚舉類和模式匹配的知識就分享到這里了,期待你的鼓勵,這將是我創(chuàng)作的不竭動力!
到此這篇關(guān)于Rust指南枚舉類與模式匹配精講的文章就介紹到這了,更多相關(guān)Rust枚舉類與模式匹配內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Rust字符串深度解析String與str的問題小結(jié)
在Rust編程語言中,字符串處理是一個核心概念,但與其他語言不同的是,Rust提供了兩種主要的字符串類型:String和&str,本文介紹Rust字符串深度解析String與str的問題,感興趣的朋友跟隨小編一起看看吧2026-03-03
Rust中用enum實現(xiàn)多參數(shù)Hook機制完整代碼
在 Rust 中,如果想為enum實現(xiàn)一個帶多參數(shù)的 Hook 機制,可以結(jié)合模式匹配和枚舉來處理,這種方式可以擴展到支持不同類型的輸入?yún)?shù)和邏輯處理,下面通過示例代碼介紹Rust中用enum實現(xiàn)多參數(shù)Hook機制,感興趣的朋友一起看看吧2024-12-12

