为了理解尝试monad与未处理异常
问题描述:
我想学习如何使用在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]键入。 我在这里做错了什么..?
答
问题在于,在第二个示例中,您在输入Try[T]
上下文之前抛出异常。
在你的第一个例子中,运行时strToInt("a")
,你已经在Try[T]
的背景下,由于代码desugered到:
strToInt("3").flatMap(_ => strToInt("a"))
由于strToInt
第一次调用成功,一切之后执行它在理解内部是在Try
的上下文中。但是,在第二个例子中,我们有相反:
strToInt("a").flatMap(_ => strToInt("3"))
strToInt("a")
将抛出一个RuntimeException
,因为我们在Try
背景是仍不,它仅适用于当您尝试解析s
到Int
。
要完全避免这种情况,将尝试匹配模式前上涨:
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)