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
forList
)
这意味着每次我们想要提取值时,都必须在选项上进行模式匹配。看起来不太整洁,但还是有可能的
我们可以在任何地方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意味着乐趣