最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Scala中優(yōu)雅的處理Null問(wèn)題

 更新時(shí)間:2021年08月30日 12:04:53   作者:SunnyRivers  
Spark 采用混合方式,大部分情況下使用 Option,但個(gè)別時(shí)候出于性能原因才使用了null。一個(gè)很好的習(xí)慣是當(dāng)有方法返回值可能為null的時(shí)候,使用Option來(lái)代替,本文給大家介紹Scala處理Null的知識(shí)詳解,一起看看吧

前言

如果在scala代碼還在使用ids!=null,可能會(huì)被有的人嘲笑,都什么年代了,竟然還有這樣的寫法,NullPointerException見(jiàn)少了吧?
不過(guò),據(jù)統(tǒng)計(jì):
Spark 源代碼使用了 821 次 Option 關(guān)鍵字,但它也直接在像if (ids != null)。

Spark 采用混合方式,大部分情況下使用 Option,但個(gè)別時(shí)候出于性能(這里主要是為了給使用這返回提示信息)原因才使用了null。

一個(gè)很好的習(xí)慣是當(dāng)有方法返回值可能為null的時(shí)候,使用Option來(lái)代替。

什么是Option

標(biāo)準(zhǔn)類庫(kù)中Option類型用樣例類來(lái)表示那種可能存在、也可能不存在的值。
Option的有兩個(gè)子類,Some 和 None,Some包裝了某個(gè)值,如Some(“Jack”),而None表示沒(méi)有值。

有的小伙伴看到依然云里霧里的,因此直接上一個(gè)簡(jiǎn)單的例子,來(lái)感受一下這個(gè)Option究竟是什么東西:

煮個(gè)栗子

這里寫了一個(gè)把字符串轉(zhuǎn)為數(shù)值的方法,輸入的是字符串,輸出的這里注意一下,并不是直接輸出Int,而且一個(gè)泛型為Int的Option

def toInt(in: String): Option[Int] = {
  try {
    Some(Integer.parseInt(in.trim))
  } catch {
    case e: NumberFormatException => None
  }
}

如何使用這個(gè)函數(shù):

toInt("s") match {
  case Some(i) => println(i)
  case None => println("您輸入的字符串無(wú)法轉(zhuǎn)為數(shù)字")
}

簡(jiǎn)單的總結(jié)一下這個(gè)Option的使用,其實(shí)就是把你原本要返回的類型,直接返回泛型為該類型的Option,然后寫正常返回值的時(shí)候返回Some,異常的時(shí)候返回None即可。而調(diào)用方法的時(shí)候,需要用到match case分別做處理。

有人看到這里可能會(huì)抱怨:一個(gè)簡(jiǎn)單的null判斷,寫了這么一大堆,還不如java中的直接用i!=null來(lái)判斷簡(jiǎn)單粗暴呢。

但是如果這個(gè)toInt函數(shù)是別人寫的,你是個(gè)使用者,你一定會(huì)遇到如下問(wèn)題:

  • 你沒(méi)有讀API文檔,根本不知道toInt可能會(huì)返回一個(gè)null,并且可能你寫的代碼會(huì)拋出NullPointerException
  • 你讀了API文檔,并且也有很多使用這個(gè)函數(shù)的經(jīng)驗(yàn),知道它可能會(huì)返回null,因此你肯定會(huì)寫如下代碼來(lái)處理可能出現(xiàn)的空指針異常
Integer i = toInt(someString);
if (i == null) {
    System.out.println("您輸入的字符串無(wú)法轉(zhuǎn)為數(shù)字");
} else {
    System.out.println(i);
}

該代碼并不比 Scala的Option和match方法差,但你確實(shí)必須閱讀API文檔才能知道必須得這樣處理。

3.當(dāng)然還可以通過(guò)拋出NumberFormatException來(lái)處理null或者其他一些異常情況

Option的好處不僅如此

比如想統(tǒng)計(jì)下面list中的總和,這些字符串有的可以轉(zhuǎn)為Int,有的不可以

val bag = List("1", "2", "foo", "3", "bar")

要實(shí)現(xiàn)這個(gè)需求,感覺(jué)要寫很多代碼才能實(shí)現(xiàn),其實(shí)在scala中只要一行代碼就可以實(shí)現(xiàn):

val sum = bag.flatMap(toInt).sum

為什么可以這么簡(jiǎn)單的就實(shí)現(xiàn):
我們的toInt方法返回的是Some[Int]或None,而flatMap知道如何處理這些值,所以實(shí)現(xiàn)起來(lái)就小菜一碟了,而且還很容易閱讀和理解。

這就是使用Option/Some/None 模式真正牛叉的地方了

簡(jiǎn)單的總結(jié)java null 與 scala Option

如果你用別人寫的java方法,那么一般需要閱讀API文檔,或者是使用后拋出了NullPointException后,查文檔和資料發(fā)現(xiàn),需要處理這個(gè)空指針異常。那么scala Option我們?cè)谑褂煤瘮?shù)的時(shí)候,可以看到返回值是個(gè)Option[Int](直接在IDE中就能看到返回值類型,不需要去閱讀該函數(shù)的API文檔),說(shuō)明開(kāi)發(fā)這個(gè)函數(shù)的人一定用了Option/Some/None這一套組合拳,因此就知道用match case來(lái)解決了。

在我看來(lái),其實(shí)從寫代碼的角度來(lái)看代碼量并沒(méi)有減少,優(yōu)點(diǎn)有兩:

  • 更具有可讀性,
  • 避免在使用函數(shù)的時(shí)候,出現(xiàn)空指針異常 Option的缺點(diǎn)

Option的缺點(diǎn)

有的人會(huì)說(shuō),你前言中都說(shuō)了連spark源碼都不是一律采用Option來(lái)處理null值,你既然上面吹的神乎其神的,人家干嘛不全部用Option?
這里就得說(shuō)一下Option的一個(gè)缺點(diǎn):
無(wú)法說(shuō)出某件事失敗的原因(也就是為什么你得到了一個(gè)None而不是一個(gè)Some),因?yàn)楦揪涂床坏藉e(cuò)誤異常信息

對(duì)此scala 的解決方案是使用Either Left 和 Right來(lái)處理異常信息

Either Left Right簡(jiǎn)介與使用

Either其實(shí)用起來(lái)和Option很像,不同的是Either可以返回一個(gè)字符串來(lái)描述發(fā)生的問(wèn)題。

Either 和Option的比較:
Either 就像 Option
Right 就像 Some
Left 就像 None (不過(guò)它是寫出發(fā)生問(wèn)題的原因)

還是搞一段代碼來(lái)解釋

/**
  * 這里寫個(gè)簡(jiǎn)單的方法來(lái)演示,如何寫一個(gè)返回值為Either的方法
  * 以及Either中Left和Right的用法
  */
def divideXByY(x: Int, y: Int): Either[String, Int] = {
  if (y == 0) Left("零不能作為除數(shù)")
  else Right(x / y)
}

// 使用 Either, Left, and Right的幾種不同方式
println(divideXByY(1, 0))
println(divideXByY(1, 1))
divideXByY(1, 0) match {
  case Left(s) => println("Answer: " + s)
  case Right(i) => println("Answer: " + i)
}

上面divideXByY方法返回的是一個(gè)Either[String, Int],這個(gè)泛型String就是Left方法中傳入的數(shù)據(jù)類型,而Int就是Right方法傳入的數(shù)據(jù)類型。

通過(guò)上面的例子,會(huì)發(fā)現(xiàn)這一套東西和Option/Some/None使用起來(lái)很像,唯一不同的是,Either將出錯(cuò)的信息可以傳回,使用者可以看到異常信息。我們看看官網(wǎng)是怎么說(shuō)的:

Represents a value of one of two possible types (a disjoint union.) Instances of Either are either an instance of Left or Right.
A common use of Either is as an alternative to Option for dealing with possible missing values. In this usage,
scala.None is replaced with a Left which can contain useful information. Right takes the place of Some.
Convention dictates that Left is used for failure and Right is used for success.
說(shuō)白了就是我上面寫的,如果要返回錯(cuò)誤信息給使用者,就用Either。不過(guò)根據(jù)我經(jīng)驗(yàn),一般這樣的場(chǎng)景不算多。因此最長(zhǎng)用的還是Option。

到此這篇關(guān)于Scala中如何優(yōu)雅的處理Null的文章就介紹到這了,更多相關(guān)Scala處理Null內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot中如何進(jìn)行統(tǒng)一異常處理

    SpringBoot中如何進(jìn)行統(tǒng)一異常處理

    大家好,本篇文章主要講的是SpringBoot中如何進(jìn)行統(tǒng)一異常處理,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下
    2022-02-02
  • SpringBoot項(xiàng)目整合攔截器詳解

    SpringBoot項(xiàng)目整合攔截器詳解

    這篇文章主要介紹了SpringBoot項(xiàng)目整合攔截器詳解,java里的攔截器是動(dòng)態(tài)攔截Action調(diào)用的對(duì)象,它提供了一種機(jī)制可以使開(kāi)發(fā)者在一個(gè)Action執(zhí)行的前后執(zhí)行一段代碼,攔截器用于在某個(gè)方法或者字段被訪問(wèn)之前進(jìn)行攔截,然后再之前或者之后加入某些操作,需要的朋友可以參考下
    2023-10-10
  • java springmvc 注冊(cè)中央調(diào)度器代碼解析

    java springmvc 注冊(cè)中央調(diào)度器代碼解析

    這篇文章主要介紹了java springmvc 注冊(cè)中央調(diào)度器代碼解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • java中的類為什么只能用public修飾?

    java中的類為什么只能用public修飾?

    這篇文章主要介紹了java中的類為什么只能用public修飾,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2020-12-12
  • java開(kāi)發(fā)工作中對(duì)InheritableThreadLocal使用思考

    java開(kāi)發(fā)工作中對(duì)InheritableThreadLocal使用思考

    這篇文章主要為大家介紹了java開(kāi)發(fā)工作中對(duì)InheritableThreadLocal使用思考詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • Spring?Boot自動(dòng)配置的原理及@Conditional條件注解

    Spring?Boot自動(dòng)配置的原理及@Conditional條件注解

    這篇文章主要介紹了Spring?Boot自動(dòng)配置的原理及@Conditional條件注解,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的朋友可以參考一下
    2022-07-07
  • Spring?Boot教程之必須了解的核心概念

    Spring?Boot教程之必須了解的核心概念

    這篇文章主要介紹了Spring?Boot系列教程中的關(guān)于學(xué)習(xí)Spring?Boot必須了解的核心概念的相關(guān)資料,需要的朋友可以參考下
    2022-08-08
  • SPRING FRAMEWORK BEAN作用域和生命周期原理解析

    SPRING FRAMEWORK BEAN作用域和生命周期原理解析

    這篇文章主要介紹了SPRING FRAMEWORK BEAN作用域和生命周期原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • java中synchronized鎖的升級(jí)過(guò)程

    java中synchronized鎖的升級(jí)過(guò)程

    這篇文章主要介紹了java中synchronized鎖的升級(jí)過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java創(chuàng)建多線程的兩種方式對(duì)比

    Java創(chuàng)建多線程的兩種方式對(duì)比

    在Java中創(chuàng)建線程的方式有兩種,第一種是直接繼承Thead類,另一種是實(shí)現(xiàn)Runable接口。那么這兩種方式孰優(yōu)孰劣呢?這就是本文需要探討的內(nèi)容范疇了,看官們請(qǐng)仔細(xì)向下看
    2014-10-10

最新評(píng)論

丹阳市| 琼中| 星座| 简阳市| 文昌市| 石阡县| 石阡县| 冀州市| 宁晋县| 海城市| 桦甸市| 芜湖县| 富源县| 共和县| 子长县| 东丽区| 太谷县| 吐鲁番市| 礼泉县| 德保县| 石阡县| 祁阳县| 甘谷县| 若尔盖县| 饶平县| 昌黎县| 邵阳市| 建平县| 平南县| 黄梅县| 永济市| 江西省| 都兰县| 荥经县| 乌什县| 南开区| 高要市| 出国| 延寿县| 将乐县| 卫辉市|