Scala 为什么有Option.get方法

Scala 为什么有Option.get方法,scala,scala-collections,api-design,Scala,Scala Collections,Api Design,为什么方法get在选项中定义,而不是在部分中定义 可以应用模式匹配或使用foreach,map,flatMap,getOrElse,如果调用None.get,则不存在运行时异常的危险 是否真的有这样的情况,get方法非常方便,可以证明这一点?使用get方法提醒我使用Java,“我不必检查null,因为我知道已经设置了var”,然后看到NullPointerException,这是没有充分理由的。Martin Odersky在2007年加入了这个项目,所以我想我们需要问问他的动机。早期版本具有ge

为什么方法
get
选项中定义,而不是在
部分中定义

可以应用模式匹配或使用
foreach
map
flatMap
getOrElse
,如果调用
None.get
,则不存在运行时异常的危险


是否真的有这样的情况,
get
方法非常方便,可以证明这一点?使用
get
方法提醒我使用Java,“我不必检查null,因为我知道已经设置了var”,然后看到
NullPointerException

,这是没有充分理由的。Martin Odersky在2007年加入了这个项目,所以我想我们需要问问他的动机。早期版本具有
getOrElse
语义

Option.get有时在您知道您拥有的值不是空的情况下非常有用,因为它不是由类型系统捕获的。但是,只有在您尝试过以下操作后,您才应该尝试:

  • 安排你的类型来表达这些知识
  • 使用上面提到的选项处理方法(flatMap、getOrElse等),但它们都不适合
对于一次性/交互式代码(REPL、工作表等),它也很方便。

如果您检查提供的代码。很明显,为什么和 当它被使用时。get用于在确定文件中有
某些东西时取消装箱

选项
。它还可以作为一个可继承的方法,其中
None.get
抛出一个异常,而
Some.get
取消对内容的装箱。

前言

Scala是以JVM的兼容性为目标创建的

因此,很自然地,
Exception
s和
try/catch
应该被视为语言的一部分,至少对于java互操作性来说是如此

考虑到这一前提,现在就要包括可能在代数数据类型(或case类,如果您愿意)中抛出错误的接口


回答问题

假设我们只在
一些
实例中封装
get
方法(或
head
for
List
) 这意味着每次我们想要提取值时,都必须在
选项上进行模式匹配。看起来不太整洁,但还是有可能的

我们可以在任何地方
getOrElse
,但这意味着如果使用命令式样式,我不能通过错误堆栈发出失败信号(这在scala中是不被禁止的,上次我检查时)


我在这里的观点是,
getOrElse
headOption
可以在需要时强制执行函数样式,但是如果命令是适合问题或程序员偏好的选择,那么
get
head
是很好的选择。

在某些情况下,当您的
选项
结果为
时,没有追索权,您希望抛出异常。因此,与其写作

myOption match {
  case Some(value) => // use value
  case None => throw new RuntimeException("I really needed that value")
}
你可以简单地写

myOption.get // might throw an exception
它还使
选项
从Java与
定义的
一起使用时更加方便:

if (myOption.isDefined()) process(myOption.get());
else // it's a None!

我想这是为了从
Java
进行迁移。有时它在
REPL
中很有用。我希望有一个编译器选项将
.get
视为错误。同样,为什么有List.head方法?有趣的是,即使是Haskell也有,当应用于空列表时会导致运行时错误。为了更接近问题的核心:为什么会有异常(或其他使函数部分化的事情)?有人提到过吗?Martin Odersky没有在该提交中添加
get
方法。已经有方法了。他将一个实现从
Option
移动到
Some
None
。方法
get
位于
Option
中,因为……这并不意味着什么
getOrElse
也可以在
Some
None
中抽象和独立实现,或者保持原样(减去@inline),并将
get
作为私有方法。这差不多就是它。我确实认为这样做的语法开销应该更高,以减少对那些认为“该死,我的价值在
选项中”
!我怎么才能把它拿出来?!哦,
获取
“@MyseriousDan-也许吧,尽管这也是你可以很容易地用静态分析工具标记出来的东西。当然,但代码分析是一种回顾性工具。我的目标是首先让开发人员对使用它感到内疚,这样他们设计的代码就不需要它了。在我看来,一个三个字母的单词中没有引起内疚的单词,如
unsafeGet
get,但这将导致bugsipromise
是不够的威慑。如果在代码库中找到1500个实例并重新编译以将这些错误推给用户,那么检测它并没有多大帮助。我的观点是,非法使用的数量远远超过合法使用的数量,我们不应该针对偶尔出现的后一种情况进行优化。使用
get
的人在使用它时需要感到内疚,以确保它确实是必要的,并且不能做得更干净。@ManuelSchmidt:我大体上同意,只是在少数情况下
get
仍然是合理的。我最近写了一些代码来返回一些(拓扑排序)有向图,如果有,否则没有。另外,有些代码可以在任意图中打断循环并返回非循环图。第三个例程运行循环中断代码,然后获得拓扑排序。对结果调用
get
是合理的,因为我们可以证明它是安全的——即使类型没有捕获该属性。(你可以用类型来表示,但我认为这太过分了)。我不同意get和head意味着命令式编程,或者getOrElse/HeadOption意味着乐趣