简体   繁体   English

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

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

Should Success (the child of Try) return Some(null) when converting it to Option ? Success (Try的子Some(null)在将其转换为Option时是否会返回Some(null)

Eg Try(null).toOption in scala 2.11.7 returns Some(null) Success's toOption method implemented simply by returning Some(value) . 例如,scala 2.11.7中的Try(null).toOption返回Some(null) Success的toOption方法,只需返回Some(value) Why doesn't it return None when converting Try to option using toOption method if underlying value of try is null ? 如果try的底层值为null为什么在使用toOption方法转换Try to option时不返回None

Here's the source of toOption from Scala 2.11.7: 这是Scala 2.11.7中toOption的来源:

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

I agree with Bruno that this is confusing, it should probably read 我同意布鲁诺的观点,这令人困惑,应该可以阅读

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

Absolutely not. 绝对不。 Option is NOT a null-safety container, it is a Functor, a Monad, and a Collection of size 0 or 1. It can contain null, just like a List can. Option不是一个null安全容器,它是一个Functor,一个Monad,以及一个大小为0或1的Collection。它可以包含null,就像List一样。 Just like Try can. 就像尝试可以。

Although it is often used for null-safety, due to Option.apply converting null to None and general Scala best practices avoiding the use of null. 虽然它通常用于null安全性,但由于Option.apply将null转换为None而一般的Scala最佳实践避免使用null。

Furthermore, the language does not allow you to define a type parameter that is not null, so Try[A] is implicitly saying that A can be null, according to the language, and Option[A] means that the value can be null too. 此外,该语言不允许您定义非null的类型参数,因此根据语言, Try[A]隐式地说A可以为null,而Option[A]意味着该值也可以为null 。 It is only by convention that A usually is not null. 按惯例,A通常不为空。

It would be incorrect to convert a Try containing a null value to None, as it would be truncating the range of A implicitly. 将包含空值的Try转换为None是不正确的,因为它会隐式截断A的范围。 Some[A](null) is valid, for any A that is an AnyRef 对于作为AnyRef任何ASome[A](null)有效

The language design is at odds with its own best practices here. 语言设计与其自身的最佳实践不一致。 The language does next-to-nothing to help enforce it. 该语言几乎没有任何帮助来强制执行它。 Null is a valid bottom type. Null是有效的底部类型。 An ideal world would allow users to define non-nullable types and the compiler to track null introduction and elimination, which would eliminate these sorts of surprises. 一个理想的世界将允许用户定义非可空类型和编译器来跟踪空引入和消除,这将消除这些类型的意外。

Note that if we made toOption convert null values to None, then the following equality would not hold: 请注意,如果我们将toOption转换为None值,则以下等式将不会成立:

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

which could lead to other surprises in your code when seemingly harmless refactorings were done, perhaps some minor for comprehension rearrangement that suddenly changes a result from None to something else because of the order of operations that appear to be order independent. 当看似无害的重构完成时,这可能会导致代码中的其他惊喜,也许是因为理解重新安排而导致的结果突然从None变为其他东西,因为操作顺序似乎与顺序无关。

Scala should have had two types for this, one which is a null safety container ( Maybe ?) and breaks the law above in general, because it can not contain null, and another that is just like today's Option, but without Option.apply -- an optional value. Scala应该有两种类型,一种是null安全容器( Maybe ?)并且一般违反上面的法则,因为它不能包含null,而另一种就像今天的Option,但没有Option.apply - - 可选值。

Option.apply is the odd man out, and should be removed, IMO. Option.apply是奇怪的人,应该被删除,IMO。

For example, consider the following, all of which evaluate to Some(null) : 例如,考虑以下内容,所有这些都评估为Some(null)

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

Option is used all across the collections library to be a collection of size 0 or 1, and not a null safety device . 整个集合库中的选项用作大小为0或1的集合,而不是空安全设备 It makes no sense for these to return None as long as Option is a primarily collection of size 0 or 1, and not a 'non-null' wrapper. 只要Option是一个大小为0或1的主要集合,而不是一个'非null'包装器,返回None就没有意义。 If Option was such a thing, then it would not be used across the collections library to represent optional values, such as with find and headOption above. 如果Option是这样的东西,那么它不会在集合库中用于表示可选值,例如上面的findheadOption

If anyone truly wants to get into the weeds on the topic, have fun: https://groups.google.com/forum/#!msg/scala-internals/1DXdknjt9pY/_moEcbNd4noJ 如果有人真的想要了解这个主题的杂草,那就玩得开心: https//groups.google.com/forum/#! msg / scala-internals / Ddddjt9pY / _ emEcbNd4noJ

5 years ago I thought it was a great idea to get rid of Some(null) . 5年前我认为摆脱Some(null)是一个好主意。 Now I would propose getting rid of Option.apply and creating a different type for non-nullness. 现在我建议摆脱Option.apply并为非null值创建一个不同的类型。 Call it Maybe . 叫它Maybe Then one could have Try.toMaybe along side Try.toOption 然后可以在Try.toMaybe旁边有Try.toOption

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

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