scala的option和some

對(duì)于學(xué)習(xí) Scala 的 Java? 開發(fā)人員來說找前,對(duì)象是一個(gè)比較自然、簡(jiǎn)單的入口點(diǎn)判族。在 本系列 前幾期文章中躺盛,我介紹了 Scala 中一些面向?qū)ο蟮木幊谭椒ǎ@些方法實(shí)際上與 Java 編程的區(qū)別不是很大形帮。我還向您展示了 Scala 如何重新應(yīng)用傳統(tǒng)的面向?qū)ο蟾拍畈郾梗业狡淙秉c(diǎn),并根據(jù) 21 世紀(jì)的新需求重新加以改造辩撑。Scala 一直隱藏的一些重要內(nèi)容將要現(xiàn)身:Scala 也是一種函數(shù)語(yǔ)言(這里的函數(shù)性是與其他 dys 函數(shù)語(yǔ)言相對(duì)而言的)界斜。

Scala 的面向函數(shù)性非常值得探討,這不僅是因?yàn)橐呀?jīng)研究完了對(duì)象內(nèi)容合冀。Scala 中的函數(shù)編程將提供一些新的設(shè)計(jì)結(jié)構(gòu)和理念以及一些內(nèi)置構(gòu)造各薇,它們使某些場(chǎng)景(例如并發(fā)性)的編程變得非常簡(jiǎn)單。

C# 2.0 可變?yōu)?null 值的類型其他語(yǔ)言已試圖通過各種方法解決 “可 null 值化” 問題:C++ 一直都忽略了這個(gè)問題,直至最后確定 null 和 0 是不同的值峭判。Java 語(yǔ)言仍然沒有徹底解決這個(gè)問題开缎,而是依賴于自動(dòng)裝箱(autobox)— 將原語(yǔ)類型自動(dòng)轉(zhuǎn)換為它們的包裝器對(duì)象(在 1.1 以后引入)— 幫助 Java 程序員解決問題。一些模式愛好者建議每種類型都應(yīng)該有一個(gè)對(duì)應(yīng)的 “Null Object”林螃,即將自己的所有方法重寫為不執(zhí)行任何操作的類型(實(shí)際上是子類型)的實(shí)例 — 實(shí)踐證明這需要大量工作奕删。C# 1.0 發(fā)布后,C# 設(shè)計(jì)者決定采取一種完全不同的方法解決 null 值化問題疗认。

C# 2.0 引入了可變?yōu)?null 值的類型 的概念完残,重要的是添加了語(yǔ)法支持,認(rèn)為任何特定值類型(基本指原語(yǔ)類型)都可以通過將 null 封裝到一個(gè)泛型/模板類 Nullable<T>横漏,從而提供 null 支持谨设。Nullable<T> 本身是在類型聲明中通過 ? 修飾符號(hào)引入。因此缎浇,int? 表示一個(gè)整數(shù)也可能為 null铝宵。

表面上看,這似乎很合理华畏,但是事情很快就變得復(fù)雜起來鹏秋。int 和 int? 是否應(yīng)該被視為可兼容類型,如果是的話亡笑,什么時(shí)候?qū)?int 提升為 int?侣夷,反之呢?當(dāng)將 int 添加到 int? 會(huì)發(fā)生什么仑乌,結(jié)果會(huì)是 null 嗎百拓?這類問題等等。隨后類型系統(tǒng)進(jìn)行了一些重要的調(diào)整晰甚,可變?yōu)?null 值的類型隨后包含到了 2.0 中 — 而 C# 程序員幾乎完全忽略了它們衙传。

回顧一下 Option 類型的函數(shù)方法,它使 Option[T] 和 Int 之間的界限變得很清晰厕九,看上去要比其他方法更加簡(jiǎn)單蓖捶。在那些圍繞可變?yōu)?null 值類型的反直覺(counterintuitive)提升規(guī)則之間進(jìn)行比較時(shí),尤其如此扁远。(函數(shù)領(lǐng)域?qū)υ搯栴}近二十年的思考是值得的)俊鱼。要使用 Option[T] 必須付出一些努力,但是總的來說畅买,它產(chǎn)生了更清晰的代碼和期望并闲。
.本月,您將首次進(jìn)入 Scala 的函數(shù)編程領(lǐng)域谷羞,查看大多數(shù)函數(shù)語(yǔ)言中常見的四種類型:列表(list)帝火、元組(tuple)、集合(set)和 Option 類型。您還將了解 Scala 的數(shù)組犀填,后者對(duì)其他函數(shù)語(yǔ)言來說十分新鮮萌京。 這些類型都提出了編寫代碼的新方式。當(dāng)結(jié)合傳統(tǒng)面向?qū)ο筇匦詴r(shí)宏浩,可以生成十分簡(jiǎn)潔的結(jié)果。

使用 Option(s)

在什么情況下靠瞎,“無” 并不代表 “什么也沒有”比庄?當(dāng)它為 0 的時(shí)候,與 null 有什么關(guān)系乏盐。

對(duì)于我們大多數(shù)人都非常熟悉的概念佳窑,要在軟件中表示為 “無” 是一件十分困難的事。例如父能,看看 C++ 社區(qū)中圍繞 NULL 和 0 進(jìn)行的激烈討論神凑,或是 SQL 社區(qū)圍繞 NULL 列值展開的爭(zhēng)論,便可知曉一二何吝。 NULL 或 null 對(duì)于大多數(shù)程序員來說都表示 “無”溉委,但是這在 Java 語(yǔ)言中引出了一些特殊問題。

考慮一個(gè)簡(jiǎn)單操作爱榕,該操作可以從一些位于內(nèi)存或磁盤的數(shù)據(jù)庫(kù)查找程序員的薪資:API 允許調(diào)用者傳入一個(gè)包含程序員名字的 String瓣喊,這會(huì)返回什么呢?從建模角度來看黔酥,它應(yīng)該返回一個(gè) Int藻三,表示程序員的年薪;但是這里有一個(gè)問題跪者,如果程序員不在數(shù)據(jù)庫(kù)中(可能根本沒有雇用她棵帽,或者已經(jīng)被解雇,要不就是輸錯(cuò)了名字……)渣玲,那么應(yīng)該返回 什么逗概。如果返回類型是 Int,則不能返回 null忘衍,這個(gè) “標(biāo)志” 通常表示沒有在數(shù)據(jù)庫(kù)中找到該用戶(您可能認(rèn)為應(yīng)該拋出一個(gè)異常仗谆,但是大多數(shù)時(shí)候數(shù)據(jù)庫(kù)丟失值并不能視為異常,因此不應(yīng)該在這里拋出異常)淑履。

在 Java 代碼中隶垮,我們最終將方法標(biāo)記為返回 java.lang.Integer,這迫使調(diào)用者知道方法可以返回 null秘噪。自然狸吞,我們可以依靠程序員來全面歸檔這個(gè)場(chǎng)景,還可以依賴程序員讀取 精心準(zhǔn)備的文檔。這類似于:我們可以要求經(jīng)理傾聽我們反對(duì)他們要求的不可能完成的項(xiàng)目期限蹋偏,然后經(jīng)理再進(jìn)一步把我們的反對(duì)傳達(dá)給上司和用戶便斥。

Scala 提供了一種普通的函數(shù)方法,打破了這一僵局威始。在某些方面枢纠,Option 類型或 Option[T],并不重視描述黎棠。它是一個(gè)具有兩個(gè)子類 Some[T] 和 None 的泛型類晋渺,用來表示 “無值” 的可能性,而不需要語(yǔ)言類型系統(tǒng)大費(fèi)周折地支持這個(gè)概念脓斩。實(shí)際上木西,使用 Option[T] 類型可以使問題更加清晰(下一節(jié)將用到)。

在使用 Option[T] 時(shí)随静,關(guān)鍵的一點(diǎn)是認(rèn)識(shí)到它實(shí)質(zhì)上是一個(gè)大小為 “1” 的強(qiáng)類型集合八千,使用一個(gè)不同的值 None 表示 “nothing” 值的可能性。因此燎猛,在這里方法沒有返回 null 表示沒有找到數(shù)據(jù)恋捆,而是進(jìn)行聲明以返回 Option[T],其中 T 是返回的原始類型重绷。那么鸠信,對(duì)于沒有查找到數(shù)據(jù)的場(chǎng)景,只需返回 None论寨,如下所示:

@Test def simpleOptionTest =  
{  
  val footballTeamsAFCEast =  
    Map("New England" -> "Patriots",  
        "New York" -> "Jets",  
        "Buffalo" -> "Bills",  
        "Miami" -> "Dolphins",  
        "Los Angeles" -> null)  
    
  assertEquals(footballTeamsAFCEast.get("Miami"), Some("Dolphins"))  
  assertEquals(footballTeamsAFCEast.get("Miami").get(), "Dolphins")  
  assertEquals(footballTeamsAFCEast.get("Los Angeles"), Some(null))  
  assertEquals(footballTeamsAFCEast.get("Sacramento"), None)  
} 

注意星立,Scala Map 中 get 的返回值實(shí)際上并不對(duì)應(yīng)于傳遞的鍵。相反葬凳,它是一個(gè) Option[T] 實(shí)例绰垂,可以是與某個(gè)值有關(guān)的 Some(),也可以是 None火焰,因此可以很清晰地表示沒有在 map 中找到鍵劲装。如果它可以表示 map 上存在某個(gè)鍵,但是有對(duì)應(yīng)的 null 值昌简,這一點(diǎn)特別重要了占业。比如清單 1 中 Los Angeles 鍵。

通常纯赎,當(dāng)處理 Option[T] 時(shí)谦疾,程序員將使用模式匹配,這是一個(gè)非常函數(shù)化的概念犬金,它允許有效地 “啟用” 類型和/或值念恍,更不用說在定義中將值綁定到變量六剥、在 Some() 和 None 之間切換,以及提取 Some 的值(而不需要調(diào)用麻煩的 get() 方法)峰伙。清單 2 展示了 Scala 的模式匹配:

清單 2. 巧妙的模式匹配

@Test def optionWithPM =  
{  
  val footballTeamsAFCEast =  
    Map("New England" -> "Patriots",  
        "New York" -> "Jets",  
        "Buffalo" -> "Bills",  
        "Miami" -> "Dolphins")  
          
  def show(value : Option[String]) =  
  {  
    value match  
    {  
      case Some(x) => x  
      case None => "No team found"  
    }  
  }  
    
  assertEquals(show(footballTeamsAFCEast.get("Miami")), "Dolphins")  
} 
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末疗疟,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子瞳氓,更是在濱河造成了極大的恐慌策彤,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件匣摘,死亡現(xiàn)場(chǎng)離奇詭異店诗,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)恋沃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來必指,“玉大人囊咏,你說我怎么就攤上這事∷穑” “怎么了梅割?”我有些...
    開封第一講書人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)葛家。 經(jīng)常有香客問我户辞,道長(zhǎng),這世上最難降的妖魔是什么癞谒? 我笑而不...
    開封第一講書人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任底燎,我火速辦了婚禮,結(jié)果婚禮上弹砚,老公的妹妹穿的比我還像新娘双仍。我一直安慰自己,他們只是感情好桌吃,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開白布朱沃。 她就那樣靜靜地躺著,像睡著了一般茅诱。 火紅的嫁衣襯著肌膚如雪逗物。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,462評(píng)論 1 302
  • 那天瑟俭,我揣著相機(jī)與錄音翎卓,去河邊找鬼。 笑死摆寄,一個(gè)胖子當(dāng)著我的面吹牛莲祸,可吹牛的內(nèi)容都是我干的蹂安。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼锐帜,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼田盈!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起缴阎,我...
    開封第一講書人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤允瞧,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后蛮拔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體述暂,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年建炫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了畦韭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡肛跌,死狀恐怖艺配,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情衍慎,我是刑警寧澤转唉,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站稳捆,受9級(jí)特大地震影響赠法,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜乔夯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一砖织、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧末荐,春花似錦镶苞、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至剃幌,卻和暖如春聋涨,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背负乡。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工牍白, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人抖棘。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓茂腥,卻偏偏與公主長(zhǎng)得像狸涌,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子最岗,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容