簡體   English   中英

默認情況下F#中的引用是不可為空的嗎?

[英]Are references non-nullable by default in F#?

我知道在C#中它不是,而且它是像Haskell這樣的語言(如果我沒有錯),所以認為F#默認也有相同的語義。

即使它在C#中不存在,它也是語言的限制,而不是運行時,對吧? 就像F#或其他一些新的.NET語言實際上可以將其作為默認值實現而不使用任何類型的hack。

在F#中,如果在F#代碼中定義新類或其他類型,則默認情況下它將是非可空的,在某種意義上,例如

type MyClass() = ...
...
let x : MyClass = null   // does not compile

然而,它編譯為.NET IL代碼作為一個類,它是.NET上的引用類型,可以為null,因此C#可以創建該類型的空值,甚至在F#中

let x : MyClass = Unchecked.defaultOf<MyClass>

會給你一個空的。 所以在這個意義上,它非常“運行時的限制” - 你永遠不能創建一個.NET語言,它既可以“將一個類暴露給C#,使它看起來像一個普通的類”,也可以“確保實例那種類型永遠不會為空“。 所以你總是要在這里做出務實的決定。 當你留在F#中時,F#試圖阻止你發生事故和處理null的煩惱,但是如果你處理interop或.NET運行時的細節,那么在一天結束時,null總是處於閑置狀態。 (十億美元的錯誤。)

除了Brian提出的觀點之外,值得一提的是,當您在F#中定義新類型時,如果這是您想要的行為,則可以選擇允許null值。 這是通過AllowNullLiteral屬性完成的:

[<AllowNullLiteral>]
type T1() = class end

type T2() = class end

let t1 : T1 = null
let t2 : T2 = null // compiler error

編輯

關於您的后續問題,是的,此屬性適用於類型本身。 絕大多數F#類型都不會應用此屬性; 如果你有一個帶有參數的函數或方法,你想允許它有一個有效的類型值或一個“類似null”的sentinel值,那么你可以使用一個option類型:

let myFunc (o:option<T2>) = 
  match o with
  | None -> "No value passed in"
  | Some(t2) -> "A T2 instance was passed in"

選項類型類似於C#中的可空類型,除了它們不限於包裝結構(以及與此主題無關​​的一些其他微小差異)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM