Scala';实施方案的选择

Scala';实施方案的选择,scala,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

在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
  }
在OOP世界中,我将如何假设:

  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))
  }
后者有什么问题

是否在
选项[A]
中使用
匹配
,这是第三种方法(看起来像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] {
}

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

我想,由于scala同时支持函数式和命令式以及面向it的java程序,这是让它们更容易填充的东西之一。
来自java程序员

val opt: Option[String] = ???
if (!opt.isEmpty) {
  //do something with opt.get
} else {
  //do some default...
}
可能比功能性方式更容易理解(即使使用getOrElse)

@Victor Moroz在其中一篇评论中写道,使用模式匹配代替
此匹配{None=>default\u val;Some(v)=>v}


这不仅让刚接触函数世界的程序员更难理解,而且成本更高,因为选项的用途更多,instanceOf的成本也比简单的if高。

这是表达式问题的一个方面,在这种情况下,我个人会选择
match
,因为:a.)您不会有任何其他这种特性的实现(既因为这是该数据类型背后的逻辑,也因为下面的第二点);当您无法预先预测所有实现时,子类型多态性非常有用。b、 )它是密封的,因此您将获得详尽的模式匹配警告/错误。Scala实现可能使用标志表示速度,bool标志检查速度快且没有间接性。您可能还对scalaz的
Maybe
实现感兴趣:相应的讨论:
isEmpty
将在Scala中定义,如果我需要它,只要我停留在函数范式中,我就不这么做。对于
get
也是一样,对于
None
,我真的需要
get
?我会使用
getOrElse
orElse
。您可以使用模式匹配检查
选项的内容。我认为这应该是Scala的首选方式。scalaz开发人员甚至为
选项
构建了一个名为
Maybe
的替代品,而不使用不安全的
get
。对于将选项视为零或一个元素的集合的用例,需要isEmpty。需要模式匹配的问题是,您将使隐式instanceof和cast成为必需的。对于可以用一个
if
表达式处理的东西来说,它也要详细得多。
if(isEmpty)default\u val else获取
vs
此匹配{None=>default\u val;Some(v)=>v}
。在前一种情况下,最多有2个多态调用(
isEmpty
get
),后者可能在幕后使用
instanceOf
,但只使用一次。我想演员是免费的。当然,在现实生活中,它会短得多
x getOrElse default\u val
如果你想争论设计应该改变,你必须和Martin Odersky谈谈,但我认为你不会走得太远。我只是在解释我认为的原因。
instanceOf
比多态调用成本更高
isEmpty
?哪怕是其中的两个(包括
get
)?我怀疑,他们应该是平等的。虽然同意Java的论点,但我猜Java程序员不会使用
选项
,他们有
null
NullPointerException
。也许我的问题是错误的,不是Scala为什么这样做,而是应该如何做,我应该遵循Scala的路径,还是其他两个路径之一。