1. 程式人生 > >scala中Either的一種使用場景

scala中Either的一種使用場景

未註冊 錯誤 用戶 異常 鏈接 正常的 進行 scala 除了

用scala有一年多了,對於scala中的Option和Try使用的較為頻繁,對其應用場景相對熟悉一些。而對於Either,仔細回想一下卻發現幾乎(完全)沒有使用過,其實並不是沒有遇到過Either的使用場景,只是遇到的時候不知道能夠使用Either來解決此問題。
昨天在網上偶然看到一篇介紹Either的文章,發現有一種場景可以使用Either來解決,具體是這樣的:

  web系統中,Controller層調用service層方法,根據郵箱查詢註冊的用戶User,如果未取到User,則需要知道是什麽原因導致的。

定義一個方法,根據登錄郵箱查詢User對象,方法簽名如: def getUserByEmail(email:String):User

註意方法的返回值類型,這裏返回的是User對象。在運行時會發生如下三種情況:

  1、正常返回null

  2、正常返回User

  3、發生異常拋出Exception。

對於情況1,調用處如果想知道是為什麽返回了null,是因為email的格式錯誤?還是因為該email沒有註冊的用戶? 該種方法簽名是沒辦法把失敗原因返回給調用處的 。
那麽我們考慮能否把返回結果類型User修改為Try[User],即:def getUserByEmail(email:String):Try[User]
  對於剛才的情況1,如果是因為email格式不對,我們在方法體內可以封裝一個Failure(RuntimeException("郵箱格式錯誤"))返回給調用處。而如果是該郵箱未註冊,未查詢到該用戶,如果再封裝一個Exception就不合適了。因為查不到用戶屬於正常的邏輯,不屬於異常範疇,這種方式是不可取的。
那麽我們再考慮把返回值類型Try[User]修改為Option[User],即:def getUserByEmail(email:String):Option[User]


  這樣,只是把把返回結果null修改為None,並未達到我們想要的目的
這時,我們就可以考慮把返回值類型修改為Either[String,User],即:def getUserByEmail(email:String):Either[String,User]

  如果查詢到User,那麽返回一個Right(user)即可,如果郵箱格式錯誤,則返回一個Left("郵箱格式錯誤"),如果該郵箱未進行註冊,則返回Left("該郵箱未進行註冊");如果運行中發生Exception,可以直接拋出,也可以封裝為Left("發生XXX異常")返回給調用處。
除了通過Either來返回失敗信息,我們也可以使用Tuple2[String,User]類型來實現想要的結果,在失敗的時候返回Tuple2("失敗原因描述",null),只是相對於Either來說,不是那麽便捷。

使用方式可見如下偽代碼:

 1  @Test
 2   def testEither(): Unit = {
 3     getUserByEmail("[email protected]") match {
 4       case Right(user) => ???
 5       case Left(msg) => println("查詢用戶失敗,原因:" + msg)
 6     }
 7   }
 8 
 9   def getUserByEmail(email: String): Either[String, User] = {
10     if (email無效) {
11       return Left("郵箱格式錯誤")
12     } else {
13       if (未查詢到註冊郵箱) {
14         return Left("該用戶不存在")
15       } else {
16         return Right(user)
17       }
18     }
19   }

=========================================

原文鏈接:scala中Either的一種使用場景

=========================================

-------end

scala中Either的一種使用場景