Scala实现Option的选择

Vic*_*roz 5 scala

它是如何在 Scala 中完成的:

  sealed trait Option[+A] {
    def get: A
    def isEmpty: Boolean
    def map[B](f: A => B): Option[B] =
      if (isEmpty) None else Some(f(this.get))
  }
  object None extends Option[Nothing] {
    def isEmpty = true
    def get = throw new NoSuchElementException("None.get")
  }
  case class Some[+A](x: A) extends Option[A] {
    def isEmpty = false
    def get = x
  }
Run Code Online (Sandbox Code Playgroud)

我如何在面向对象世界中假设它:

  sealed trait Option[+A] {
    def map[B](f: A => B): Option[B]
  }
  object None extends Option[Nothing] {
    def map[B](f: Nothing => B): Option[B] = this
  }
  case class Some[+A](get: A) extends Option[A] {
    def map[B](f: A => B): Option[B] = Some(f(get))
  }
Run Code Online (Sandbox Code Playgroud)

后者有什么问题?

Scala 中的函数式编程使用matchin Option[A]trait,这是第三种方式(看起来像 Haskell,但为什么呢?)为什么不利用子类型多态?

更新:我提到的第三种方式:

sealed trait Option[+A] {
  def map[B](f: A => B): Option[B] = this match {
    case None => None
    case Some(a) => Some(f(a))
  }
}
object None extends Option[Nothing] {
}
case class Some[+A](get: A) extends Option[A] {
}
Run Code Online (Sandbox Code Playgroud)

reg*_*ert 1

我不确定您是否打算这样做,但是您遗漏了isEmpty和 的声明get,任何想要检查任意内容Option而不需要向下转换为 的人都需要这些声明Some。由于这两种方法都需要由两个子类定义,并且map可以根据它们进行定义,因此我认为原因是最好map在一个地方定义,利用其他方法的子类实现,而不是定义map在三个地方。