2017-10-15 85 views
1

我想學習如何使用在scala中用於理解。爲了理解嘗試monad與未處理異常

在下面的示例代碼(RESULT1),

如果在理解引發未處理的異常的最後一條語句, 代碼不破和嘗試[INT]返回。

但是,如果語句的順序改變爲理解(結果2)。運行時異常被拋出。

package simpleTryExample 

import scala.util.Try 


object SimpleTryExample { 

    def main(args: Array[String]): Unit = { 

    val result1 = for { 
     a <- strToInt("3") 
     b <- strToInt("a") 
    } yield (a + b) 

    println("result1 is " + result1) 

    val result2 = for { 
     a <- strToInt("a") 
     b <- strToInt("3") 
    } yield (a + b) 

    println("result2 is " + result2) 

    } 

    def strToInt(s: String): Try[Int] = { 
    s match { 
     case "a" => 
     println("input is a") 
     throw new RuntimeException("a not allowed") 
     case _ => println("other then a") 
    } 
    Try(s.toInt) 
    } 
} 

輸出: -

other then a 
input is a 
Exception in thread "main" java.lang.RuntimeException: a not allowed 
    at simpleTryExample.SimpleTryExample$.strToInt(SimpleTryExample.scala:30) 
    at simpleTryExample.SimpleTryExample$.main(SimpleTryExample.scala:18) 
    at simpleTryExample.SimpleTryExample.main(SimpleTryExample.scala) 
result1 is Failure(java.lang.RuntimeException: a not allowed) 
input is a 

我期待RESULT2是一個Try [INT]鍵入。 我在這裏做錯了什麼..?

回答

2

問題在於,在第二個示例中,您在輸入Try[T]上下文之前拋出異常。

在你的第一個例子中,運行時strToInt("a"),你已經在Try[T]的背景下,由於代碼desugered到:

strToInt("3").flatMap(_ => strToInt("a")) 

由於strToInt第一次調用成功,一切之後執行它在理解內部是在Try的上下文中。但是,在第二個例子中,我們有相反:

strToInt("a").flatMap(_ => strToInt("3")) 

strToInt("a")將拋出一個RuntimeException,因爲我們在Try背景是仍不,它僅適用於當您嘗試解析sInt

要完全避免這種情況,將嘗試匹配模式前上漲:

def strToInt(s: String): Try[Int] = { 
    Try { 
    s match { 
     case "a" => 
     println("input is a") 
     throw new RuntimeException("a not allowed") 
     case _ => println("other then a") 
    } 
    s.toInt 
    } 
} 

而現在我們得到:

other then a 
input is a 
result1 is Failure(java.lang.RuntimeException: a not allowed) 
input is a 
result2 is Failure(java.lang.RuntimeException: a not allowed)