rust解決嵌套——Option類型的map和and_then方法的使用
先提一個(gè)建議如果是通過rust官網(wǎng)入門的話,個(gè)人感覺《通過例子學(xué) Rust》會(huì)比《Rust 程序設(shè)計(jì)語言》更好一些。
我這里的例子實(shí)際上也是官網(wǎng)上的例子,對(duì)于看一遍不太清晰的例子,我會(huì)選擇自己寫下來。
這篇文章假設(shè)你已經(jīng)了解了關(guān)于Option類型的一些概念(實(shí)際上是rust用來處理空值的工具)。
map方法的使用
需求:假設(shè)我想吃一種食物,這個(gè)食物需要經(jīng)過削皮、切塊和煮熟這三個(gè)線性的流程,此外在這三個(gè)流程之前,我還要判斷這個(gè)原材料是否存在,只有以上條件全部滿足,才能達(dá)成eat的目標(biāo)。
我們可以這樣去設(shè)計(jì):食物本身是一個(gè)Option選項(xiàng),此外每經(jīng)過上面的一個(gè)流程,就可以將食物包裹在一個(gè)對(duì)應(yīng)的元組結(jié)構(gòu)體之中。于是我們有了下面的寫法:
struct Peeled(String);
struct Choped(String);
struct Cooked(String);
// 削皮
fn peel(food: Option<String>) -> Option<Peeled> {
match food {
Some(food) => Some(Peeled(food)),
None => None,
}
}
// 切塊
fn chop(peeled_food: Option<Peeled>) -> Option<Choped> {
match peeled_food {
Some(Peeled(food)) => Some(Choped(food)),
None => None,
}
}
// 烹飪
fn cook(choped_food: Option<Choped>) -> Option<Cooked> {
match choped_food {
Some(Choped(food)) => Some(Cooked(food)),
None => None,
}
}
// 吃
fn eat(food: Option<Cooked>) {
match food {
Some(Cooked(food)) => println!("俺今天吃了{(lán)food}"),
None => println!("沒吃"),
}
}嘗試完整走完這個(gè)流程
let real_food = Some(String::from("豬頭肉"));
eat(cook(chop(peel(real_food))));明顯可以看到這里有一個(gè)函數(shù)的嵌套,不是非常雅觀,那么我們可以使用Option類型的map方法對(duì)三個(gè)處理過程進(jìn)行改寫,改成一個(gè)函數(shù)叫process_food
fn process_food(food: Option<String>) -> Option<Cooked> {
food.map(|f| Peeled(f))
.map(|Peeled(f)| Choped(f))
.map(|Choped(f)| Cooked(f))
}這個(gè)map當(dāng)中是一個(gè)閉包,以第一個(gè)閉包為例,它只處理Some的情況,它會(huì)將Some(food:String)轉(zhuǎn)換成Some(Peeled(food)),否則直接返回None,當(dāng)然這里還涉及到一個(gè)解構(gòu)的問題,上面的f實(shí)際上全部是函數(shù)的參數(shù)food包裹的那個(gè)String(講的很抽象)。
可以調(diào)用一下,實(shí)際上還是能運(yùn)行的
let real_food1 = Some(String::from("燒雞"));
eat(process_food(real_food1));and_then方法的使用
需求,有一些食物,我只吃能飛和有腿的,如果符合要求就以Some(food)的形式返回
enum Food {
Fish,
Chiken,
Cow,
}
// 進(jìn)行能飛和有腿的檢測,能通過的話就用Some包裹起來
fn has_legs(food: Food) -> Option<Food> {
match food {
Food::Fish => None,
_ => Some(food),
}
}
fn can_fly(food: Food) -> Option<Food> {
match food {
Food::Chiken => Some(food),
_ => None,
}
}
fn eat1(food: Option<Food>) {
match food {
Some(_food) => println!("i can eat it"),
None => println!("i am hungury"),
}
}將上面的兩個(gè)檢測函數(shù)組合成一個(gè)
fn test(food: Food) -> Option<Food> {
match has_legs(food) {
None => None,
Some(food) => match can_fly(food) {
Some(food) => Some(food),
None => None,
},
}
}這里的test又變成了一個(gè)match的嵌套,這里的檢測在流程上沒有順序要求,當(dāng)然你可以通過改寫match的流程來固定順序,可以用and_then來進(jìn)行改寫
fn test1(food: Food) -> Option<Food> {
has_legs(food).and_then(can_fly)
}eat1(test(Food::Chiken)); eat1(test(Food::Fish)); eat1(test1(Food::Cow));
運(yùn)行起來都是一樣的。
這兩個(gè)方法的用法情境有什么不同呢?恕我才疏學(xué)淺,暫時(shí)不能用準(zhǔn)確的言語進(jìn)行概括
rust基礎(chǔ)學(xué)習(xí)歷程
目前的水平只能說是入門,之前分別在21和22年入門過兩次,均是失敗告終,一方面rust確實(shí)火星,另一方面我自學(xué)編程當(dāng)時(shí)只有js基礎(chǔ)。
23年初的這次入門終于成功了,原因有二,一是我學(xué)了ts和golang+hello world程度的c++,對(duì)類型、棧堆、指針之類的概念有了點(diǎn)基礎(chǔ)的理解。二是我明白了rust那些火星般的新特點(diǎn)是針對(duì)編程中的老問題提出的,從實(shí)用角度去理解能更好掌握這些新的特點(diǎn)。
我認(rèn)為rust的特點(diǎn)是:你會(huì)比以往更了解自己寫的代碼。
希望能有更多人學(xué)習(xí)這門語言,我也會(huì)盡可能以一個(gè)業(yè)余者的身份更新一些rust或者其他編程的基礎(chǔ)知識(shí)。
到此這篇關(guān)于rust解決嵌套——Option類型的map和and_then方法的文章就介紹到這了,更多相關(guān)rust Option類型的map和and_then方法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Rust結(jié)構(gòu)體的定義與實(shí)例化詳細(xì)講解
結(jié)構(gòu)體是一種自定義的數(shù)據(jù)類型,它允許我們將多個(gè)不同的類型組合成一個(gè)整體。下面我們就來學(xué)習(xí)如何定義和使用結(jié)構(gòu)體,并對(duì)比元組與結(jié)構(gòu)體之間的異同,需要的可以參考一下2022-12-12
Rust使用Channel實(shí)現(xiàn)跨線程傳遞數(shù)據(jù)
消息傳遞是一種很流行且能保證安全并發(fā)的技術(shù),Rust也提供了一種基于消息傳遞的并發(fā)方式,在rust里使用標(biāo)準(zhǔn)庫提供的Channel來實(shí)現(xiàn),下面我們就來學(xué)習(xí)一下如何使用Channel實(shí)現(xiàn)跨線程傳遞數(shù)據(jù)吧2023-12-12
詳解Rust編程中的共享狀態(tài)并發(fā)執(zhí)行
雖然消息傳遞是一個(gè)很好的處理并發(fā)的方式,但并不是唯一一個(gè),另一種方式是讓多個(gè)線程擁有相同的共享數(shù)據(jù),本文給大家介紹Rust編程中的共享狀態(tài)并發(fā)執(zhí)行,感興趣的朋友一起看看吧2023-11-11

