scala中Either的一種使用場景
用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的一種使用場景