如果Scala方法可以抛出/返回错误但具有单位返回类型,那么它应具有哪种返回类型?

时间:2016-12-24 11:41:31

标签: scala

因此,通常当我们运行既可以失败又返回值的方法时,我们可以将方法返回类型编码为Either[SomeErrorType, ReturnType]。但很多时候我们正在为其副作用运行方法,因此返回类型为Unit

我当然可以返回Either[SomeErrorType, Unit],但这看起来确实很奇怪。

我也可以只返回一个Option[SomeErrorType],但它看起来并没有那么好(并打破了与其他Either[SomeErrorType, NonUnitReturnType] s可能存在的对称性。

在这些情况下你的做法是什么?

  1. def m(): Unit // and implicitly know that exceptions can be thrown?;
  2. def m(): Either[SomeErrorType, Unit] // this is odd;
  3. def m(): Option[SomeErrorType] // this is odd, as it makes it look as the return type of M()on a successful run is an error code.
  4. 我无法想到的其他内容?
  5. 由于

2 个答案:

答案 0 :(得分:10)

我在这种情况下使用Try[Unit]

它编码该方法的结果成功或失败并带有一些Exception,可以进一步处理。

  • vs T => Unit Try将错误提升到应用程序级别,在签名中编码可能会出现一些错误,并允许应用程序将其作为值处理。
  • VS。 Option[T] =>选项只能编码操作具有值
  • VS。 Either[SomeErrorType, Unit] => Try使用monadic结构更容易。

我使用过这样的东西来实施支票。 (想象的例子)

for {
    entity <- receiveEntity // Try[Entity]
    _ <- isRelational(entity)
    _ <- isComplete(entity)
    _ <- isStable(entity)
} yield entity

每张支票的格式为:Entity => Try[Unit]

如果所有检查都未通过检查失败的第一个错误,则返回entity

答案 1 :(得分:2)

尚未提及的另一个选项是来自catsValidated。到目前为止提到的所有选项(TryEitherOption)都是monad,而Validated是一个应用函子。实际上,这意味着您可以从返回Validated的多个方法中累积错误,并且可以并行执行多个验证。这可能与您无关,这与原始问题有点正交,但我仍然觉得在这种情况下值得一提。

至于原始问题,使用Unit返回类型作为副作用函数是完全正常的。当您定义&#34;真实&#34;时,此功能也可以返回错误这一事实不应该妨碍您。 (右,成功等)返回类型。因此,如果我要从原始选项中进行选择,请转到Either[Error, Unit]。对我来说绝对不奇怪,如果有人发现它有任何缺点,我想知道它们。