[英]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
任何A
, Some[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是這樣的東西,那么它不會在集合庫中用於表示可選值,例如上面的find
和headOption
。
如果有人真的想要了解這個主題的雜草,那就玩得開心: 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.