我是Scala的新手。我正在研究其中一个网站的try-catch块,在那里我发现Scala也提供了Try。 Try和try-catch块都执行捕获异常的工作。现在我的问题是Scala已经有一个try-catch块表现不错,那么为什么scala引入了Try?在Scala中尝试try-catch有什么优点和用例?
答案 0 :(得分:2)
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的方式。