【发布时间】:2015-03-19 20:10:41
【问题描述】:
我是 Scala 的新手,对处理异常的各种方法有些困惑,并正在寻找有关该主题的最佳实践建议。我正在编写一个简单的方法来使用现有的阻塞 SDK 检索客户。可能的结果是:
- 找到客户
- 找不到客户(从 SDK 返回 NotFoundException)
- 与远程服务器通信时出错(SDK 抛出一些其他异常)
所以我希望我的方法有一个返回类型Future[Option[Customer]],并为上述每种情况返回:
- 成功的未来:一些(客户)
- 成功的未来:无
- 失败的未来
这是我用 try/catch 写的:
private def findCustomer(userId: Long): Future[Option[Customer]] = future {
try {
Some(gateway.find(userId))
} catch {
case _: NotFoundException => None
}
}
这很好用,对我来说似乎很干净,但似乎并不是真正的“Scala 方式”——有人告诉我要避免使用 try/catch。所以我一直在寻找一种方法来改用Try 来重写它。
这里有 2 个(我认为)行为完全相同的变体,使用 Try。
变体 A:
private def findCustomer(userId: Long): Future[Option[Customer]] = future {
Try(
Some(gateway.find(userId))
).recover {
case _: NotFoundException => None
}.get
}
变体 B:
private def findCustomer(userId: Long): Future[Option[Customer]] = future {
Try(
Some(gateway.find(userId))
).recover {
case _: NotFoundException => None
}
} flatMap {
case Success(s) => Future.successful(s)
case Failure(f) => Future.failed(f)
}
我不是 A 的忠实粉丝(尽管它比 B 更简洁),因为 .get 似乎有点危险。 B 绝对是最明确的,但将 Try 案例映射到相应的 Future 结果似乎很无聊。
一个有经验的 Scala 程序员会如何写这个?
【问题讨论】:
标签: scala exception-handling coding-style