2012-06-21 253 views
9

在F#口頭禪似乎有一個內臟迴避null,Nullable<T>之流。作爲交換,我們應該改用選項類型。說實話,我並沒有真正看到差異。選項類型和可空類型有什麼區別?

  • 我的F#選項類型的理解是,它允許你指定一個類型,可以包含任何正常的值,或None的。例如,Option<int>允許除None之外的所有int可以具有的值。

  • 我對C#可空類型的理解是,它允許您指定一個可以包含任何正常值的類型,或null。例如,除了null之外,還可以使用Nullable<int>也可以具有的所有值,即int?

有什麼區別?做一些詞彙替換NullableOption,nullNone,你基本上有同樣的事情。什麼是關於null的大驚小怪?

+2

這是關於儘早避免邏輯錯誤 - 使用'option',你會得到編譯器警告/錯誤,無法檢查'None'; 'null'你不會。 – ildjarn

+0

因此,理論上,如果有一個C#模式匹配,可以確保您處理了'null'的情況,那麼這將是一次洗牌? –

+0

國際海事組織,幾乎沒有其他人會否認'null'的_semantic_的敏感性。 – ildjarn

回答

16

F#選項一般情況下,你可以爲任何類型的'T創建Option<'T>

Nullable<T>是一個非常奇怪的類型;您只能將其應用於結構,儘管Nullable類型本身就是一個結構,但它不能應用於其自身。所以你不能創建Nullable<Nullable<int>>,而你可以創建Option<Option<int>>。他們必須做一些框架魔法才能讓Nullable工作。無論如何,這意味着對於Nullables而言,如果類型是一個類或一個結構,則必須先知道它,如果它是一個類,則只需使用null而不是Nullable。這是一個醜陋的漏洞抽象;它的主要價值似乎與數據庫互操作性有關,因爲我認爲在數據庫域中處理「int或no value」對象是很常見的。

我認爲,.Net框架只是一個醜陋的混亂,當涉及到空和Nullable。你可以爭辯說F#通過Option或者說它通過暗示你避免只是空/ Nullable(除非絕對必要用於互操作)而將你從混亂中解救出來,並且專注於清潔解決方案與Option秒。你可以找到有意見的人。

你也可以看到

Best explanation for languages without null

+0

在回答_why_ F#增加'選項<_>'值得強調的是'Nullable'與'null'緊密相關,F#試圖從考慮中刪除。 – Daniel

+0

@Daniel,'option'來自ML/OCaml,而F#則來自OCaml-compat。但是,是的,大多數情況下,F#試圖將null僅歸爲'.net interop'場景。 – Brian

2

的優勢,使用option是,它使明確,一個變量可以包含任何值,而空類型離開它隱含的。給定一個像這樣的定義:

string val = GetValue(object arg); 

類型系統不記錄val是否可以爲空,或者如果arg爲null會發生什麼。這意味着需要在功能邊界進行重複檢查以驗證主叫方和被叫方的假設。

隨着模式匹配,使用選項類型可以靜態地檢查,以確保這兩種情況下代碼被處理,例如,下面的代碼產生一個警告:

let f (io: int option) = function 
| Some i -> i 
5

因爲每個.NET參考類型可以有這額外的,無意義的價值 - 無論它是否有 null,可能性存在,你必須檢查它 - 因爲Nullable使用null作爲它的「沒什麼」的表示,我認爲這是消除所有的怪異(F#所做的),並要求「無」的可能性是明確的。 Option<_>這樣做。

4

有什麼區別?

F#,您可以選擇是否希望你的類型是一個option類型,當你這樣做,建議您檢查None,使存在或不存在的None在類型明確。

C#強制每個引用類型允許null,並且不鼓勵您檢查null

所以它僅僅是一個差異的默認值。

用Nullable和Option,null和None做一些詞彙替換,你基本上有同樣的事情。什麼是關於null的大驚小怪?

正如SML,OCaml和Haskell等語言所示,刪除null可從實際代碼中刪除大量運行時錯誤。原始創作者null甚至將其描述爲他的「billion dollar mistake」。

相關問題