成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

引入Option優雅地保證健壯性

開發 開發工具
通過引入Option,既規避了可能出現的一些錯誤,又能避免編寫繁瑣的if判斷。

[[182563]]

REA的Ken Scambler在其演講《2 Year of Real World FP at REA》中,總結了選擇函數式編程的三個原因:Modularity, Abstraction和Composability。

函數式編程強調純函數(Pure Function),這是模塊化的一個重要基礎,因為對于純函數而言,可以不用考慮調用的上下文,就可以根據函數的輸入推斷函數的執行結果。這也就是Ken所謂的:

 You can tell what it does without Looking at surrounding context.

Ken在演講中給出了一個案例:

  1. def parseLocation(str: String): Location = { 
  2.   val parts = str.split(",") 
  3.   val secondStr = parts(1) 
  4.   val parts2 = secondStr.split(" ") 
  5.   Location(parts(0), parts2(0), parts(1).toInt)} 

仔細閱讀這段代碼,你會發現這段代碼是不健壯的,可能存在如下錯誤:

  • 作為input的str可能為null
  • parts(0)和parts(1)可能導致索引越界
  • parts2(0)可能導致索引越界
  • parts(1)未必是整數,調用toInt可能導致類型轉換異常

這段代碼隱含的錯誤還可能被廣泛地蔓延到系統的其他地方,只要該函數被調用。這種蔓延可能會因為更多嵌套的調用而產生級聯的錯誤效應。例如:

  1. def doSomethingElse(): Unit = { 
  2.   // ...Do other stuff 
  3.   parseLocation("Melbourne, VIC 3000")} 

而doSomethingElse()函數又被其他函數調用,這些潛在的缺陷會分布到各個直接或間接的調用點。這意味著代碼會繼承它所調用代碼的錯誤以及副作用,使得對代碼功能的推理(reasoning)變得近乎不可能,更不用說代碼的模塊化(modularity)了。

我們當然可以通過對null進行檢測來避免出現這些錯誤。然而看看各種出現null值的可能分支,需要我們做各種條件判斷,想象這樣的代碼都讓人不寒而栗。引入Option類型就可以很好地封裝這種可能性。按照Ken的說法就是:

 All possibilities have been elevated into the type system.
  1. def parseLocation(str: String): Option[Location] = { 
  2.  val parts = str.split(",") 
  3.  for { 
  4.    locality <- parts.optGet(0) 
  5.    theRestStr <- parts.optGet(1) 
  6.    theRest = theRestStr.split(" ") 
  7.    subdivision <- theRest.optGet(0) 
  8.    postcodeStr <- theRest.optGet(1) 
  9.    postcode <- postcodeStr.optToInt 
  10.  } yield Location(locality, subdivision, postcode)} 

以上代碼中,split()函數返回的類型為Array[String],該類型自身是沒有optGet()函數的。但是我們可以為Array[String]定義隱式轉換:

  1. implicit class StringArrayWrapper(array: Array[String]) { 
  2.     def optGet(index:Int): Option[String] = { 
  3.         if (array.length > index) Some(array(index)) else None 
  4.     }} 

optToInt方法可以如法炮制。

Ken的解決方案并沒有考慮到parseLocation函數入參str存在null值的可能,故而在對str調用split方法時仍然有可能導致拋出空指針異常。因此進一步,我們還可以修改parseLocation函數的定義:

  1. def parseLocation(optStr: Option[String]): Option[Location] 

顯然,通過引入Option,既規避了前面分析可能出現的錯誤,又能避免編寫繁瑣的if判斷。這里的關鍵點是Option對兩種可能性(None與Some)的封裝。它由兩個代數類型Some與None構成,前者包含了一個值,而后者則包含了一個不存在的值。事實上,Option是一個Maybe Monad,實現了flatMap與filter,因而在Scala中可以用for comprehension來訪問。

【本文為51CTO專欄作者“張逸”原創稿件,轉載請聯系原作者】

戳這里,看該作者更多好文

責任編輯:趙寧寧 來源: 51CTO專欄
相關推薦

2018-06-29 14:51:41

Java健壯性實踐

2023-11-17 11:55:54

Pythonretrying庫

2021-02-26 20:07:54

安全性健壯性代碼

2021-05-27 08:15:05

CSS CSS prefer技巧

2025-02-13 00:28:26

2024-01-08 09:38:51

Java數據

2011-12-07 10:22:11

美信云網管閥值

2025-02-27 09:35:22

2025-06-06 08:00:00

上下文管理器Python開發

2021-10-11 08:08:02

Python異常程序

2022-02-15 08:38:04

錯誤邏輯異常編程程序

2021-09-01 12:03:49

Spring單元測試

2024-05-07 07:58:47

C#程序類型

2024-07-04 08:02:59

2012-12-05 09:42:09

2021-12-09 17:21:48

TypeScript TS 前端

2024-11-07 12:20:31

LinuxC語言數據類型

2022-03-01 21:25:30

對象代碼Proxy

2024-04-12 12:14:39

Rust字符串代碼

2010-09-25 15:19:01

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 天天射美女 | 欧美成年黄网站色视频 | 精精国产视频 | 午夜私人影院 | 色婷婷av99xx| 日韩欧美中文字幕在线观看 | 夜夜爽99久久国产综合精品女不卡 | 国产精品99久久久精品免费观看 | 欧美精品久久久 | 日韩精品在线观看网站 | 欧美日产国产成人免费图片 | 四虎影院美女 | 中文字幕人成人 | 成人亚洲网 | 亚洲欧洲日韩精品 中文字幕 | 天堂素人约啪 | 久久久久国产 | 一本大道久久a久久精二百 欧洲一区二区三区 | 精品欧美一区二区三区 | 999久久久| 日韩亚洲一区二区 | 欧美日韩在线一区二区 | 欧美一区二区三区日韩 | 请别相信他免费喜剧电影在线观看 | 伊人免费视频二 | 99精品免费 | 综合第一页 | 精品视频一区二区三区四区 | 久久丝袜| 91人人澡人人爽 | 日屁网站 | 男人av网 | 一区二区不卡 | 四季久久免费一区二区三区四区 | 欧美精品一 | 免费在线观看毛片 | 成人特级毛片 | 99久久精品免费看国产四区 | 精品一二三| 三级黄视频在线观看 | 成人亚洲网 |