Scala Try的toOption方法返回Some(null)

Success (Try的孩子Some(null)在将其转换为Option时返回Some(null)

例如Try(null).toOption in scala 2.11.7返回Some(null) Success的toOption方法,只需返回Some(value) 。 为什么在转换Try选项时使用toOption方法返回None ,如果try的基础值为null


这里是Scala 2.11.7的toOption的来源:

def toOption: Option[T] = if (isSuccess) Some(get) else None

我同意布鲁诺认为这是令人困惑的,它应该可以阅读

def toOption: Option[T] = if (isSuccess) Option(get) else None

绝对不。 Option不是一个空安全容器,它是一个Functor,Monad和一个大小为0或1的集合。它可以包含null,就像List一样。 就像尝试可以。

虽然它通常用于null安全,但由于Option.apply将null转换为None,并且避免使用null,因此一般Scala最佳实践也是如此。

此外,该语言不允许你定义一个不为null的类型参数,所以按照语言, Try[A]隐含地说A可以为null, Option[A]意味着该值也可以为null 。 A通常不是空的。

将包含空值的Try转换为None不正确,因为它会隐式地截断A的范围。 对于任何是AnyRef ASome[A](null)是有效的

语言设计与这里的最佳实践不符。 该语言无助于执行它。 空是有效的底部类型。 一个理想的世界将允许用户定义不可为空的类型,编译器可以跟踪空引入和消除,这将消除这些类型的意外。

请注意,如果我们使toOption将null值转换为None,那么以下相等性不会成立:

val t: Try = ...
t.toOption.map(f) == t.map(f).toOption

当看似无害的重构完成时,这可能会导致代码中的其他惊喜,也许是对理解重新排序的一些小修改,由于操作顺序似乎与顺序无关,突然将结果从无变为其他。

斯卡拉应该有两种类型,一个是无效安全容器( Maybe ?),一般违反上述法律,因为它不能包含null,另一个就像今天的Option,但没有Option.apply - - 一个可选值。

Option.apply是一个奇怪的人,应该删除,国际海事组织。

例如,考虑以下内容,所有这些评估为Some(null)

Some(Some(null)).flatten
List("a", null).find(s != "a")
List(null, "blah").headOption
Try(null).toOption

选项用于整个集合库中的一个大小为0或1的集合,而不是一个空安全设备。 只要Option是一个大小为0或1的集合,而不是'非空'包装,它们就没有任何意义。 如果Option是这样的话,那么它将不会在集合库中用来表示可选值,例如上面的findheadOption

如果有人真的想进入关于该主题的杂草,请尽情享受:https://groups.google.com/forum/#!msg/scala-internals/1DXdknjt9pY/_moEcbNd4noJ

5年前,我认为这是摆脱Some(null)的好主意。 现在我会建议摆脱Option.apply并为non-nullness创建一个不同的类型。 称它为Maybe 。 然后可以Try.toMaybe旁边Try.toOption

链接地址: http://www.djcxy.com/p/86203.html

上一篇: Scala Try's toOption method returns Some(null)

下一篇: scala hashmap get string value returns some()