2017-10-15 52 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)