簡體   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