这是Scala中的一个方法:
def method1(arg: String*): List[String] = {
try {
new MyClass(new URL(arg(0)))
.map(x => x.getRawString.toString)
}
catch {
case e: Exception => e.printStackTrace()
}
}
它提示
found : Unit
[error] required: List[String]
如果我添加了一个附加值,以便:
def method1(arg: String*): List[String] = {
val result = try {
new MyClass(new URL(arg(0)))
.map(x => x.getRawString.toString)
}
catch {
case e: Exception => e.printStackTrace()
}
result
}
它会说
found : Any
[error] required: List[String]
这很奇怪——这和第一种方法不一样吗?
无论如何,Scala 处理这种情况的标准方法是什么——从
try { .. } catch { .. }
返回一个值?
最佳答案
问题是在异常的情况下,没有返回值。所以你必须决定在这种情况下返回什么值。它可以是一个空列表(如果您真的不关心处理错误 - 不推荐!):
def method1(arg: String*): List[String] =
try {
new MyClass(new URL(arg(0)))
.map(x => x.getRawString.toString)
} catch {
case e: Exception => { e.printStackTrace(); Nil; }
}
标准的 Scala 方法是返回
Option
,这让调用者清楚地知道发生了什么:def method1(arg: String*): Option[List[String]] =
try {
Some(new MyClass(new URL(arg(0)))
.map(x => x.getRawString.toString))
} catch {
case e: Exception => { e.printStackTrace(); None; }
}
或者可能返回异常本身:
def method1(arg: String*): Either[Exception,List[String]] =
try {
Right(new MyClass(new URL(arg(0)))
.map(x => x.getRawString.toString))
} catch {
case e: Exception => Left(e)
}
由于这种模式比较常见,因此有一个特殊的 Scala 类
Try
仅出于此目的,它为这些概念赋予了有意义的名称并添加了许多有用的方法。 Try[A]
封装返回 A
的计算结果,或者如果计算失败则出现异常: sealed abstract class Try[+T]
final case class Success[+T](value: T) extends Try[T]
final case class Failure[+T](exception: Throwable) extends Try[T]
所以你的方法的字面重写将是
def method1(arg: String*): Try[List[String]] =
try {
Success(new MyClass(new URL(arg(0)))
.map(x => x.getRawString.toString))
} catch {
case e: Exception => Failure(e)
}
但是当然 Scala 有这种模式的方法(毕竟这就是
Try
的用途),所以你可以只写def method1(arg: String*): Try[List[String]] =
Try { new MyClass(new URL(arg(0)))
.map(x => x.getRawString.toString)) }
(略有不同,
Try { ... }
和 catches some Error
s )。
关于scala - 从 try-catch 返回一个值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17500955/