【问题标题】:Why does scala.util.Failure have a type parameter?为什么 scala.util.Failure 有类型参数?
【发布时间】:2017-10-18 09:36:22
【问题描述】:

scala.util.Failure 声明如下:

final case class Failure[+T](exception: Throwable) extends Try[T]`

考虑到Failure 可以很容易地声明为Try[Nothing] 的子类型,它需要一个看起来完全没有必要的类型参数T:

final case class Failure(exception: Throwable) extends Try[Nothing]`

就像None 被声明为:

object None extends Option[Nothing]

确实,额外的类型参数成为其他地方的痛点。这里是Future.zip:

def zip[U](that: Future[U]): Future[(T, U)] = {
  implicit val ec = internalExecutor
  val p = Promise[(T, U)]()
  onComplete {
    case f: Failure[_] => p complete f.asInstanceOf[Failure[(T, U)]]
    case Success(s) => that onComplete { c => p.complete(c map { s2 => (s, s2) }) }
  }
  p.future
}

行:

    case f: Failure[_] => p complete f.asInstanceOf[Failure[(T, U)]]

可以简化为:

    case f: Failure => p complete f

如果失败被声明为Try[Nothing] 的子类型。

我觉得我必须在这里遗漏一些东西。我可以为类型参数想出的唯一原因是声明一个表达式表示计算特定类型的失败,并明确表示它是一个失败,不像只使用Try[T],但我无法想象一种情况真正需要的地方。

【问题讨论】:

标签: scala types


【解决方案1】:

Failure[+T] 中的 T 在尝试从故障中恢复时派上用场:recover[U >: T](rescueException: PartialFunction[Throwable, U]): Try[U]

【讨论】:

  • 并非如此,这仍然适用于Failure 子类型Try[Nothing],就像getOrElse 适用于None 一样。
  • 没有Nothing 的子类型,并且通过扩展,在Nothing 给出的类型参数中没有协变的任何类型的子类型。根据定义Nothing是所有类型的子类型。
  • @RandallSchulz:这是不正确的。 Option[+A] 的参数是协变的,Option[Nothing] 有一个子类型None。
  • @wingedsubmariner:当然……子类型关系是自反的。只有当它是不自反的时,我所说的才是真实的。
猜你喜欢
  • 1970-01-01
  • 2016-05-04
  • 2011-11-09
  • 2019-03-15
  • 1970-01-01
  • 1970-01-01
  • 2014-12-30
  • 1970-01-01
相关资源
最近更新 更多