国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Rust】Rust學習 第六章枚舉和模式匹配

這篇具有很好參考價值的文章主要介紹了【Rust】Rust學習 第六章枚舉和模式匹配。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

本章介紹?枚舉enumerations),也被稱作?enums。枚舉允許你通過列舉可能的?成員variants) 來定義一個類型。首先,我們會定義并使用一個枚舉來展示它是如何連同數據一起編碼信息的。接下來,我們會探索一個特別有用的枚舉,叫做?Option,它代表一個值要么是某個值要么什么都不是。然后會講到在?match?表達式中用模式匹配,針對不同的枚舉值編寫相應要執(zhí)行的代碼。最后會介紹?if let,另一個簡潔方便處理代碼中枚舉的結構。

6.1?定義枚舉

定義一個枚舉

fn main() {

}

enum IpAddrKind {
    V4,
    V6,
}

現在?IpAddrKind?就是一個可以在代碼中使用的自定義數據類型了。

枚舉值

可以像這樣創(chuàng)建?IpAddrKind?兩個不同成員的實例:

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

注意枚舉的成員位于其標識符的命名空間中,并使用兩個冒號分開。這么設計的益處是現在?IpAddrKind::V4?和?IpAddrKind::V6?都是?IpAddrKind?類型的。

一個案例:

fn main() {
enum IpAddrKind {
    V4,
    V6,
}

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

let home = IpAddr {
    kind: IpAddrKind::V4,
    address: String::from("127.0.0.1"),
};

let loopback = IpAddr {
    kind: IpAddrKind::V6,
    address: String::from("::1"),
};
}

這里定義了一個有兩個字段的結構體?IpAddrIpAddrKind(之前定義的枚舉)類型的?kind?字段和?String?類型?address?字段。有這個結構體的兩個實例。第一個,home,它的?kind?的值是?IpAddrKind::V4?與之相關聯的地址數據是?127.0.0.1。第二個實例,loopback,kind?的值是?IpAddrKind?的另一個成員,V6,關聯的地址是?::1。使用了一個結構體將?kind?和?address?打包在一起,現在枚舉成員就與值相關聯了。

可以使用一種更簡潔的方式來表達相同的概念,僅僅使用枚舉并將數據直接放進每一個枚舉成員而不是將枚舉作為結構體的一部分。

fn main() {
enum IpAddr {
    V4(String),
    V6(String),
}

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

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

用枚舉替代結構體還有另一個優(yōu)勢:每個成員可以處理不同類型和數量的數據。IPv4 版本的 IP 地址總是含有四個值在 0 和 255 之間的數字部分。如果我們想要將?V4?地址存儲為四個?u8?值而?V6?地址仍然表現為一個?String,這就不能使用結構體了。

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

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

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

結構體和枚舉還有另一個相似點:就像可以使用?impl?來為結構體定義方法那樣,也可以在枚舉上定義方法。

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

impl Message {
    fn call(&self) {
        // 在這里定義方法體
    }
}

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

方法體使用了?self?來獲取調用方法的值。這個例子中,創(chuàng)建了一個值為?Message::Write(String::from("hello"))?的變量?m,而且這就是當?m.call()?運行時?call?方法中的?self?的值。

Option 枚舉和其相對于空值的優(yōu)勢

Option?是標準庫定義的另一個枚舉。Option?類型應用廣泛因為它編碼了一個非常普遍的場景,即一個值要么有值要么沒值。從類型系統(tǒng)的角度來表達這個概念就意味著編譯器需要檢查是否處理了所有應該處理的情況,這樣就可以避免在其他編程語言中非常常見的 bug。

Rust 并沒有很多其他語言中有的空值功能。空值(Null?)是一個值,它代表沒有值。在有空值的語言中,變量總是這兩種狀態(tài)之一:空值和非空值。

Rust 并沒有空值,不過它確實擁有一個可以編碼存在或不存在概念的枚舉。這個枚舉是 Option<T>,而且它定義于標準庫中,如下:

fn main() {
enum Option<T> {
    Some(T),
    None,
}
}

Option<T>?枚舉是如此有用以至于它甚至被包含在了 prelude 之中,你不需要將其顯式引入作用域。另外,它的成員也是如此,可以不需要?Option::?前綴來直接使用?Some?和?None即便如此?Option<T>?也仍是常規(guī)的枚舉,Some(T)?和?None?仍是?Option<T>?的成員。

fn main() {
    let some_number = Some(5);
    let some_string = Some("a string");
    let absent_number:Option<i32> = None;

    println!("{:#?}, {:#?}, {:#?} ", some_number, some_string, absent_number);
}

結果

【Rust】Rust學習 第六章枚舉和模式匹配,Rust,rust,學習,開發(fā)語言,keep studying,后端,筆記

如果使用?None?而不是?Some,需要告訴 Rust?Option<T>?是什么類型的,因為編譯器只通過?None?值無法推斷出?Some?成員保存的值的類型。

簡而言之,因為?Option<T>?和?T(這里?T?可以是任何類型)是不同的類型,編譯器不允許像一個肯定有效的值那樣使用?Option<T>。

fn main() {
    let x : i32 = 8;
    let y:Option<i32> = Some(10);
    let sum = x + y;
}

結果

【Rust】Rust學習 第六章枚舉和模式匹配,Rust,rust,學習,開發(fā)語言,keep studying,后端,筆記

?錯誤信息意味著 Rust 不知道該如何將?Option<i8>?與?i8?相加,因為它們的類型不同。

6.2?match控制流運算符

match?的力量來源于模式的表現力以及編譯器檢查,它確保了所有可能的情況都得到處理。

一個案例:

enum Coin {
    Penny,
    Nickel,
    Dime,
    Quarter,
}

// 使用了match
fn value_in_cents(coin : Coin) -> u8 {
    match coin {
        Coin::Penny => 1,
        Coin::Nickel => 5,
        Coin::Dime => 10,
        Coin::Quarter =>25,
    }
}

fn main() {
    let data = Coin::Nickel;
    println!("{}", value_in_cents(data));
    let data = Coin::Penny;
    println!("{}", value_in_cents(data));
    let data = Coin::Dime;
    println!("{}", value_in_cents(data));
    let data = Coin::Quarter;
    println!("{}", value_in_cents(data));
}

結果

【Rust】Rust學習 第六章枚舉和模式匹配,Rust,rust,學習,開發(fā)語言,keep studying,后端,筆記

拆開?value_in_cents?函數中的?match?來看。首先,我們列出?match?關鍵字后跟一個表達式,在這個例子中是?coin?的值。這看起來非常像?if?使用的表達式,不過這里有一個非常大的區(qū)別:對于?if,表達式必須返回一個布爾值,而這里它可以是任何類型的。

接下來是?match?的分支。一個分支有兩個部分:一個模式和一些代碼。第一個分支的模式是值?Coin::Penny?而之后的?=>?運算符將模式和將要運行的代碼分開。這里的代碼就僅僅是值?1。每一個分支之間使用逗號分隔。

當?match?表達式執(zhí)行時,它將結果值按順序與每一個分支的模式相比較。如果模式匹配了這個值,這個模式相關聯的代碼將被執(zhí)行。如果模式并不匹配這個值,將繼續(xù)執(zhí)行下一個分支,非常類似一個硬幣分類器。

每個分支相關聯的代碼是一個表達式,而表達式的結果值將作為整個?match?表達式的返回值。

綁定值的模式

匹配分支的另一個有用的功能是可以綁定匹配的模式的部分值。這也就是如何從枚舉成員中提取值的。

一個案例:

#[derive(Debug)]

enum UsState {
    Alabama,
    Alaska,
}

enum Coin {
    Penny,
    Nickel,
    Dime,
    Quarter(UsState),
}

fn value_in_cents(coin : Coin) -> u8 {
    match coin {
        Coin::Penny => 1,
        Coin::Nickel => 5,
        Coin::Dime => 10,
        Coin::Quarter(state) => {
            println!("State quater from {:?}!", state);
            25
        },
    }
}

fn main() {
    let data = Coin::Quarter(UsState::Alaska);

    println!("{}", value_in_cents(data));
}

結果

【Rust】Rust學習 第六章枚舉和模式匹配,Rust,rust,學習,開發(fā)語言,keep studying,后端,筆記

如果調用?value_in_cents(Coin::Quarter(UsState::Alaska)),coin?將是?Coin::Quarter(UsState::Alaska)。當將值與每個分支相比較時,沒有分支會匹配,直到遇到?Coin::Quarter(state)。這時,state?綁定的將會是值?UsState::Alaska。接著就可以在?println!?表達式中使用這個綁定了,像這樣就可以獲取?Coin?枚舉的?Quarter?成員中內部的州的值。

匹配Option<T>

編寫一個函數,它獲取一個?Option<i32>?并且如果其中有一個值,將其加一。如果其中沒有值,函數應該返回?None?值并不嘗試執(zhí)行任何操作。

fn main() {
    let five = Some(5);
    let five = plus_one(five);
    let six = plus_one(five);
    let none = plus_one(None);

    println!("{:?}, {:?}, {:?}", five, six, none);
}

fn plus_one(x : Option<i32>) -> Option<i32> {
    match x {
        None => None,
        Some(x) => Some(x + 1),
    }
}

結果

【Rust】Rust學習 第六章枚舉和模式匹配,Rust,rust,學習,開發(fā)語言,keep studying,后端,筆記

匹配上了就返回,匹配不上就會陷入死循環(huán),rust會報錯。

【Rust】Rust學習 第六章枚舉和模式匹配,Rust,rust,學習,開發(fā)語言,keep studying,后端,筆記?_通配符

Rust 也提供了一個模式用于不想列舉出所有可能值的場景。例如,u8?可以擁有 0 到 255 的有效的值,如果我們只關心 1、3、5 和 7 這幾個值,就并不想必須列出 0、2、4、6、8、9 一直到 255 的值。所幸不必這么做:可以使用特殊的模式?_?替代:

fn main() {
let some_u8_value = 0u8;
match some_u8_value {
    1 => println!("one"),
    3 => println!("three"),
    5 => println!("five"),
    7 => println!("seven"),
    _ => println!("emo")
}
}

?6.3?if let簡潔控制流

if let?語法讓我們以一種不那么冗長的方式結合?if?和?let,來處理只匹配一個模式的值而忽略其他模式的情況。

fn main() {
    let some_u8_value = Some(0u8);
    match some_u8_value {
        Some(3) => println!("three"),
        _ =>(),
    }
}

我們想要對?Some(3)?匹配進行操作但是不想處理任何其他?Some<u8>?值或?None?值。

可以使用?if let?這種更短的方式編寫

fn main() {
    let some_u8_value = Some(0u8);
    if let Some(3) = some_u8_value {
        println!("three");
    }
}

if let?獲取通過等號分隔的一個模式和一個表達式。它的工作方式與?match?相同,這里的表達式對應?match?而模式則對應第一個分支。

可以認為?if let?是?match?的一個語法糖,它當值匹配某一模式時執(zhí)行代碼而忽略所有其他值。

可以在?if let?中包含一個?else。else?塊中的代碼與?match?表達式中的?_?分支塊中的代碼相同,這樣的?match?表達式就等同于?if let?和?else

參考:枚舉與模式匹配 - Rust 程序設計語言 簡體中文版 (bootcss.com)文章來源地址http://www.zghlxwxcb.cn/news/detail-640706.html

到了這里,關于【Rust】Rust學習 第六章枚舉和模式匹配的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • Rust in Action筆記 第六章 內存

    Rust in Action筆記 第六章 內存

    OptionT 類型在Rust中使用了空指針優(yōu)化(null pointer optimization)來保證該類型在編譯后的二進制文件中占用0個字節(jié)。 None 變量是通過一個空指針 null pointer 來表示; 內存地址、指針、引用的區(qū)別,內存地址是指在內存中的一個字節(jié),由匯編語言提供的一個抽象;指針,有時候也

    2024年02月08日
    瀏覽(88)
  • 【Rust】Rust學習 第十八章模式用來匹配值的結構

    【Rust】Rust學習 第十八章模式用來匹配值的結構

    模式是 Rust 中特殊的語法,它用來匹配類型中的結構,無論類型是簡單還是復雜。結合使用模式和? match ?表達式以及其他結構可以提供更多對程序控制流的支配權。模式由如下一些內容組合而成: 字面值 解構的數組、枚舉、結構體或者元組 變量 通配符 占位符 這些部分描

    2024年02月11日
    瀏覽(16)
  • 【Rust】Rust學習 第十六章無畏并發(fā)

    【Rust】Rust學習 第十六章無畏并發(fā)

    安全且高效的處理并發(fā)編程是 Rust 的另一個主要目標。 并發(fā)編程( Concurrent programming ),代表程序的不同部分相互獨立的執(zhí)行,而?并行編程( parallel programming )代表程序不同部分于同時執(zhí)行 ,這兩個概念隨著計算機越來越多的利用多處理器的優(yōu)勢時顯得愈發(fā)重要。由于歷

    2024年02月12日
    瀏覽(14)
  • Rust -- 模式與匹配

    1. 模式 匹配類型中的結構(數據的形狀),結合 模式和match表達式 提供程序控制流的支配權 模式組成內容 字面量 解構的數組、枚舉、結構體、元組 變量 通配符 占位符 流程:匹配值 -- 是否擁有正確的數據 -- 運行特定的代碼 2. 使用模式的位置 match分支:由match、一個匹

    2023年04月26日
    瀏覽(23)
  • 【Rust 基礎篇】Rust 模式:高效、安全和靈活的匹配工具

    在編程中,經常需要對數據進行匹配和處理,例如從一個復雜的數據結構中提取特定的值,或者根據不同的情況執(zhí)行不同的邏輯。Rust是一門現代的系統(tǒng)編程語言,它引入了一種稱為\\\"模式\\\"(Pattern)的強大特性,使得數據的匹配和處理變得高效、安全和靈活。本篇博客將深入探

    2024年02月08日
    瀏覽(31)
  • 30天拿下Rust之模式與模式匹配

    概述 ????????Rust語言以其強大的類型系統(tǒng)和所有權模型而著稱,而模式與模式匹配則是Rust中一種非常強大且靈活的工具,它允許我們在編譯時根據數據的結構進行條件分支處理。在Rust中,模式是一種用于匹配數據的結構,它可以是一個具體的值、一個變量綁定、一個枚

    2024年04月12日
    瀏覽(45)
  • Rust編程語言入門之模式匹配

    模式是Rust中的一種特殊語法,用于匹配復雜和簡單類型的結構 將模式與匹配表達式和其他構造結合使用,可以更好地控制程序的控制流 模式由以下元素(的一些組合)組成: 字面值 解構的數組、enum、struct 和 tuple 變量 通配符 占位符 想要使用模式,需要將其與某個值進行

    2023年04月22日
    瀏覽(23)
  • 【跟小嘉學 Rust 編程】十八、模式匹配(Patterns and Matching)

    【跟小嘉學 Rust 編程】一、Rust 編程基礎 【跟小嘉學 Rust 編程】二、Rust 包管理工具使用 【跟小嘉學 Rust 編程】三、Rust 的基本程序概念 【跟小嘉學 Rust 編程】四、理解 Rust 的所有權概念 【跟小嘉學 Rust 編程】五、使用結構體關聯結構化數據 【跟小嘉學 Rust 編程】六、枚舉

    2024年02月11日
    瀏覽(22)
  • 【Rust 基礎篇】Rust 枚舉類型

    在 Rust 中,枚舉類型(Enum)是一種自定義數據類型,它允許我們定義一個值只能取自預定義列表中的變量。枚舉類型在編寫代碼時可以提供更明確的語義,使得代碼更易于理解和維護。本篇博客將詳細介紹 Rust 中的枚舉類型,包括定義、使用和模式匹配等方面的內容。 在

    2024年02月12日
    瀏覽(27)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包