【发布时间】:2018-05-21 02:47:30
【问题描述】:
我是 Scala 新手。我正在研究其中一个网站的 try-catch 块,在那里我了解到 Scala 也提供了 Try。 Try 和 try-catch 块都执行捕获异常的工作。现在我的问题是 Scala 已经有一个 try-catch 块,它表现得很好,那么为什么 scala 引入了 Try? Scala 中 Try 优于 try-catch 的优势和用例是什么?
【问题讨论】:
标签: scala
我是 Scala 新手。我正在研究其中一个网站的 try-catch 块,在那里我了解到 Scala 也提供了 Try。 Try 和 try-catch 块都执行捕获异常的工作。现在我的问题是 Scala 已经有一个 try-catch 块,它表现得很好,那么为什么 scala 引入了 Try? Scala 中 Try 优于 try-catch 的优势和用例是什么?
【问题讨论】:
标签: scala
try {} catch {}、Try monad 的目的是错误处理,但 Try 是一种功能性的错误处理方式,具有可用的功能组合。
假设您正在编写一个用于除两个数字的 API,当提供不良数据并将意外结果传播到客户端时,这将在运行应用程序的过程中爆炸。
scala> def divisionWithoutErrorHandling(x: Int, y: Int): Int = x / y
divisionWithoutErrorHandling: (x: Int, y: Int)Int
scala> val result = divisionWithoutErrorHandling(1, 0)
java.lang.ArithmeticException: / by zero
at .divisionWithoutErrorHandling(<console>:12)
... 28 elided
try catch ... 是一种强制处理错误的方式(java方式)。而如果你忘记捕捉错误(因为编译器不会在编译时告诉你),你就完蛋了。
scala> @throws(classOf[Exception]) def divisionWithErrorHandling(x: Int, y: Int): Int = x / y
divisionWithErrorHandling: (x: Int, y: Int)Int
scala> val result = divisionWithErrorHandling(1, 0) // compiler does not tell you about you need to handle errors here.
java.lang.ArithmeticException: / by zero
at .divisionWithErrorHandling(<console>:11)
... 28 elided
scala> val result = try { divisionWithErrorHandling(1, 0) } catch {case e: Exception => 0 }
result: Int = 0
现在,Try 添加了一种通过封装操作来处理操作的函数式方法。 由于 Try[T] 是一个返回类型,因此您会收到一个提醒,您需要在失败案例。
Try[T] 有两个结果 Success 或 Failure。当操作失败时,返回类型为Failure,否则为Success[T]。
scala> def divisionWithFnErrorHandling(x: Int, y: Int): Try[Int] = Try { x/y }
divisionWithFnErrorHandling: (x: Int, y: Int)scala.util.Try[Int]
scala> val result = divisionWithFnErrorHandling(1, 0)
result: scala.util.Try[Int] = Failure(java.lang.ArithmeticException: / by zero)
你也可以用Try链接操作,
scala> divisionWithFnErrorHandling(100, 2).map(x => x * 100).map(x => x + 200)
res5: scala.util.Try[Int] = Success(5200)
所以,Try[T] 告诉客户返回类型是Try[T],因此它的客户负责他们希望如何处理错误。
您也可以使用Either[Throwable, T] 进行错误处理,但这取决于您编写 API 的方式。
【讨论】: