共用方式為


明確欄位:val 關鍵字 (F#)

val 關鍵字可用來在類別或結構型別上宣告欄位但不初始化欄位。以這種方式宣告的欄位稱為「明確欄位」(Explicit Field)。為 val 關鍵字的另一種使用方式與宣告自動實作屬性的 member 關鍵字一起使用。如需自動實作屬性的詳細資訊,請參閱 屬性 (F#)

 val [ mutable ] [ access-modifier ] field-name : type-name

備註

在類別或結構型別中定義欄位的一般方式是使用 let 繫結。不過,let 繫結必須在類別建構函式中初始化,這不一定是可能、必要或所需的。當您要未初始化的欄位時,可以使用 val 關鍵字。

明確欄位可以是靜態或非靜態。access-modifier 可以是 public、private 或 internal。明確欄位預設都是公用。這不同於類別中一定是私用的 let 繫結。

在具有主要建構函式的類別型別中,明確欄位需要 DefaultValue 屬性。這個屬性指定欄位會初始化為零。欄位的型別必須支援零初始設定。如果型別是下列其中一項,型別會支援零初始設定:

  • 有零值的基本型別。

  • 支援 null 值做為一般值、異常值或值表示的型別。這包含類別、Tuple、記錄、函式、介面、.NET 參考型別、unit 型別和差別等位型別。

  • .NET 實值型別。

  • 其所有欄位都支援預設零值的結構。

注意事項警告

請注意 .NET Framework命名空間 System.ComponentModel 包含具有相同名稱的屬性。如需此屬性的詳細資訊,請參閱 DefaultValueAttribute

下列程式碼示範明確欄位的用法,並示範在有主要建構函式之類別中的 let 繫結,以做為比較。請注意 let 繫結的欄位 myInt1 為私用。當 let 繫結的欄位 myInt1 是從成員方法參考時,不需要自我識別項 this。但當您參考明確欄位 myInt2 和 myString 時,則需要自我識別項。

type MyType() =
    let mutable myInt1 = 10
    [<DefaultValue>] val mutable myInt2 : int
    [<DefaultValue>] val mutable myString : string
    member this.SetValsAndPrint( i: int, str: string) =
       myInt1 <- i
       this.myInt2 <- i + 1
       this.myString <- str
       printfn "%d %d %s" myInt1 (this.myInt2) (this.myString)

let myObject = new MyType()
myObject.SetValsAndPrint(11, "abc")
// The following line is not allowed because let bindings are private.
// myObject.myInt1 <- 20
myObject.myInt2 <- 30
myObject.myString <- "def"

printfn "%d %s" (myObject.myInt2) (myObject.myString)

其輸出如下:

11 12 abc

30 def

下列程式碼示範在沒有主要建構函式之類別中明確欄位的用法。在此情況下,不需要 DefaultValue 屬性,但所有欄位必須在針對型別定義的建構函式中初始化。

type MyClass =
    val a : int
    val b : int
    // The following version of the constructor is an error
    // because b is not initialized.
    // new (a0, b0) = { a = a0; }
    // The following version is acceptable because all fields are initialized.
    new(a0, b0) = { a = a0; b = b0; }

let myClassObj = new MyClass(35, 22)
printfn "%d %d" (myClassObj.a) (myClassObj.b)

輸出為 35 22。

下列程式碼示範在結構中明確欄位的用法。因為結構為實值型別,所以它會自動具有將欄位值設為零的預設建構函式。因此不需要 DefaultValue 屬性。

type MyStruct =
    struct
        val mutable myInt : int
        val mutable myString : string
    end

let mutable myStructObj = new MyStruct()
myStructObj.myInt <- 11
myStructObj.myString <- "xyz"

printfn "%d %s" (myStructObj.myInt) (myStructObj.myString)

輸出為 11 xyz。

明確欄位不適用於日常用途。一般而言,您應該盡可能使用類別中的 let 繫結,而不是明確欄位。在某些互通性案例中明確欄位會很有用,例如當您需要定義將用於原生 API 之平台叫用呼叫的結構時,或是在 COM Interop 案例中。如需詳細資訊,請參閱外部函式 (F#)。另一個可能需要明確欄位的情況是當您使用 F# 程式碼產生器發出不含主要建構函式的類別時。對於執行緒靜態變數或類似建構,明確欄位也是很有用。如需詳細資訊,請參閱 ThreadStaticAttribute

當關鍵字 member val 一起出現在型別定義時,它就是一個自動實作屬性的定義。如需詳細資訊,請參閱 屬性 (F#)

請參閱

參考

屬性 (F#)

類別中的 let 繫結 (F#)

其他資源

成員 (F#)