- Scala編程(第5版)
- (德)馬丁·奧德斯基等
- 1288字
- 2022-05-06 15:51:34
第12步 用map方法和for-yield變換
在指令式編程風(fēng)格中,可以當場改變數(shù)據(jù)結(jié)構(gòu)直到達成算法的目標。而在函數(shù)式編程風(fēng)格中,需要把不可變的數(shù)據(jù)結(jié)構(gòu)變換成新的數(shù)據(jù)結(jié)構(gòu)來達成目標。
不可變集合的一個重要的用于實現(xiàn)函數(shù)式變換的方法是map。與foreach方法相同,map方法也接收一個函數(shù)作為參數(shù)。與foreach方法不同的是,foreach方法用傳入的函數(shù)對每個元素執(zhí)行副作用,而map方法用傳入的函數(shù)將每個元素變換成新的值。舉例來說,如下字符串的列表:

可以像這樣將它變換成由新的字符串組成的新列表:

另一種執(zhí)行這個變換的方式是使用for表達式。可以通過yield關(guān)鍵字(而不是do)來引入需要執(zhí)行的代碼體:

for-yield生成的結(jié)果與map方法生成的結(jié)果完全一樣,因為編譯器會把for-yield表達式變換成map方法調(diào)用。[11]由于map方法返回的列表包含了由傳入的函數(shù)生成的值,因此返回的列表的元素類型將會是該函數(shù)的結(jié)果類型。在前一例中,傳入的函數(shù)返回的是字符串,因此map方法返回List[String]。如果傳入map方法的函數(shù)返回其他類型,則map方法返回的List也會以相應(yīng)的類型作為其元素類型。例如,在下面的map方法調(diào)用中,傳入的函數(shù)將字符串變換成整數(shù)來表示字符串元素的長度。因此,map方法調(diào)用的結(jié)果就是包含了這些長度的List[Int]:

像以前一樣,你也可以用帶有yield的for表達式來完成同樣的變換:

很多類型都可以使用map方法,不僅僅是List。這讓我們可以在很多類型上使用for表達式。比如說Vector,這是一個對所有它支持的操作提供“實效常量時間”(effectively constant time)性能的不可變序列。由于Vector具備帶有正確簽名的map方法,因此可以對Vector執(zhí)行像List一樣的函數(shù)式變換,可以直接調(diào)用map方法,也可以使用for-yield。例如:

請注意,當你對List執(zhí)行map操作時,得到的返回值是一個新的List;而當你對Vector執(zhí)行map操作時,得到的返回值是一個新的Vector。你會發(fā)現(xiàn)絕大多數(shù)定義了map方法的類型都具備這個模式。
最后再看一個例子,Scala的Option類型。Scala用Option表示可選的值,而不使用像Java一樣用null表達此含義的傳統(tǒng)技法。[12]Option要么是一個Some,表示值存在;要么是一個None,表示沒有值。
作為一個展示Option實際使用的案例,我們可以考查一下find方法。所有的Scala集合類型,包括List和Vector,都具備find方法,其作用是查找滿足給定前提的元素,這個前提是一個接收元素類型的參數(shù)并返回布爾值的函數(shù)。find方法的結(jié)果類型是Option[E],其中,E是集合的元素類型。find方法會逐個遍歷集合的元素,將元素傳遞給前提。如果前提返回了true,find就停止遍歷,并將當前元素包裝在Some中返回。如果find遍歷了所有元素都沒有找到能通過前提判斷的元素,就會返回None。下面是一些結(jié)果類型均為Option[String]的示例:

盡管Option不是一個集合,它也提供了map方法。[13]如果Option是一個Some,可被稱為“已定義”的可選值,則map方法將返回一個新的包含了將原始Some元素傳入map方法后得到返回值的新Option。下面的示例對startsW進行了變換,而它本來是一個包含字符串"Who"的Some:

與List和Vetcor相同,可以通過對Option執(zhí)行for-yield來完成這個變換:

如果對None執(zhí)行map,None意味著這是一個“未定義”的可選值,將得到一個None。下面是一個展示對startsH(一個None值)執(zhí)行map操作的示例:

用for-yield完成同樣的變換操作:

還可以用map方法和for-yield對其他許多類型進行變換,但就目前而言足夠了。這一步的主要目的是讓你對如何編寫典型的Scala代碼有一個直觀的認識:對不可變數(shù)據(jù)結(jié)構(gòu)進行函數(shù)式變換。
- Spring技術(shù)內(nèi)幕:深入解析Spring架構(gòu)與設(shè)計
- The React Workshop
- Web程序設(shè)計(第二版)
- Yii Project Blueprints
- Vue.js 2 Web Development Projects
- Spring Boot+MVC實戰(zhàn)指南
- Hands-On GUI Programming with C++ and Qt5
- HTML5+CSS3+JavaScript 從入門到項目實踐(超值版)
- Mastering Elixir
- C#程序設(shè)計基礎(chǔ)入門教程
- Three.js權(quán)威指南:在網(wǎng)頁上創(chuàng)建3D圖形和動畫的方法與實踐(原書第4版)
- WordPress Search Engine Optimization(Second Edition)
- Mastering ASP.NET Web API
- HikariCP數(shù)據(jù)庫連接池實戰(zhàn)
- 川哥教你Spring Boot 2實戰(zhàn)