Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 要理解,请尝试带有未处理异常的monad_Scala_Error Handling_Try Catch_For Comprehension - Fatal编程技术网

Scala 要理解,请尝试带有未处理异常的monad

Scala 要理解,请尝试带有未处理异常的monad,scala,error-handling,try-catch,for-comprehension,Scala,Error Handling,Try Catch,For Comprehension,我正在努力学习如何在scala中使用Try with进行理解 在下面的示例代码(result1)中 如果for construction中的最后一条语句引发未处理的异常, 代码不会中断,并返回Try[Int] 但是,如果为了理解而改变了语句的顺序(result2)。将引发运行时异常 package simpleTryExample import scala.util.Try object SimpleTryExample { def main(args: Array[String])

我正在努力学习如何在scala中使用Try with进行理解

在下面的示例代码(result1)中

如果for construction中的最后一条语句引发未处理的异常, 代码不会中断,并返回Try[Int]

但是,如果为了理解而改变了语句的顺序(result2)。将引发运行时异常

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)
  }
}
我希望result2是Try[Int]类型。
这里我做错了什么?

问题是,在第二个示例中,您在进入
Try[T]
上下文之前抛出异常

在第一个示例中,当运行
strotint(“a”)
时,您已经处于
Try[T]
的上下文中,因为代码被设计为:

strToInt("3").flatMap(_ => strToInt("a"))
由于第一次调用
strotint
是成功的,因此在
Try
的上下文中,在它之后执行的所有操作都是为了理解。但是,在第二个例子中,我们有相反的情况:

strToInt("a").flatMap(_ => strToInt("3"))
strotint(“a”)
将抛出一个
RuntimeException
,因为我们仍然不在
Try
上下文中,它仅在您尝试将
s
解析为
Int
时应用

要完全避免这种情况,请在模式匹配之前将try向上移动:

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)
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)