繁体   English   中英

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

[英]Scala Try's toOption method returns Some(null)

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

例如,scala 2.11.7中的Try(null).toOption返回Some(null) Success的toOption方法,只需返回Some(value) 如果try的底层值为null为什么在使用toOption方法转换Try to option时不返回None

这是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不是一个null安全容器,它是一个Functor,一个Monad,以及一个大小为0或1的Collection。它可以包含null,就像List一样。 就像尝试可以。

虽然它通常用于null安全性,但由于Option.apply将null转换为None而一般的Scala最佳实践避免使用null。

此外,该语言不允许您定义非null的类型参数,因此根据语言, Try[A]隐式地说A可以为null,而Option[A]意味着该值也可以为null 。 按惯例,A通常不为空。

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

语言设计与其自身的最佳实践不一致。 该语言几乎没有任何帮助来强制执行它。 Null是有效的底部类型。 一个理想的世界将允许用户定义非可空类型和编译器来跟踪空引入和消除,这将消除这些类型的意外。

请注意,如果我们将toOption转换为None值,则以下等式将不会成立:

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

当看似无害的重构完成时,这可能会导致代码中的其他惊喜,也许是因为理解重新安排而导致的结果突然从None变为其他东西,因为操作顺序似乎与顺序无关。

Scala应该有两种类型,一种是null安全容器( Maybe ?)并且一般违反上面的法则,因为它不能包含null,而另一种就像今天的Option,但没有Option.apply - - 可选值。

Option.apply是奇怪的人,应该被删除,IMO。

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

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

整个集合库中的选项用作大小为0或1的集合,而不是空安全设备 只要Option是一个大小为0或1的主要集合,而不是一个'非null'包装器,返回None就没有意义。 如果Option是这样的东西,那么它不会在集合库中用于表示可选值,例如上面的findheadOption

如果有人真的想要了解这个主题的杂草,那就玩得开心: https//groups.google.com/forum/#! msg / scala-internals / Ddddjt9pY / _ emEcbNd4noJ

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM