2011-02-11 61 views
6

在瞭解了很多關於此語言最重要的特性之後,我正在接近F#類。那麼,類定義的語法不是很容易理解,但現在一些主要概念對我來說很清楚,但其他的則不然。試圖瞭解F#類定義語法

1)我想知道的第一件事就是正確/不正確。我知道類可以用兩種方式定義:

  • 隱式類。這些類只有一個構造函數,並且在類的第一行中,有必要使用let綁定來定義爲其賦值的所有內部變量。
  • 顯式類。這些類有許多構造函數。他們通過val綁定接受非初始化值。這些值必須在構造函數中初始化。如果構造函數未能爲使用val綁定定義的至少一個私有變量定義值,編譯器將會發瘋。

它正確嗎?

2)我有一個問題,在明確的類中理解構造函數的語法。 考慮以下幾點:

這裏的第一個版本:

(* COMPILES :) *) 
type MyType = 
    val myval: int 
    val myother: int 
    (* Constructor *) 
    new (a: int, b: int) = { 
     myval = a; 
     myother = b; 
    } 

這裏的第二個版本:

(* COMPILES :) *) 
type MyType = 
    val myval: int 
    val myother: int 
    (* Constructor *) 
    new (a: int, b: int) = { 
     myval = a (* No semicolon *) 
     myother = b (* No semicolon *) 
    } 

這裏的最後一個版本:

(* DOES NOT COMPILE :(*) 
type MyType = 
    val myval: int 
    val myother: int 
    (* Constructor *) 
    new (a: int, b: int) = 
     myval = a (* Using the normal indent syntax, without {} *) 
     myother = b (* Using the normal indent syntax, without {} *) 

我不明白爲什麼前兩個版本編譯,第三個版本使用正常的indentati在語法上,不。 只會出現此問題,因爲成員的構造函數,我可以用縮進語法

(* COMPILES :) *) 
type MyType = 
    val myval: int 
    val myother: int 
    (* Constructor *) 
    new (a: int, b: int) = { 
     myval = a (* No semicolon *) 
     myother = b (* No semicolon *) 
    } 
    (* Indentation accepted, no {} to be inserted *) 
    member self.mymember = 
     let myvar = myval 
     myvar + 10 

爲什麼新功能(構造)需要括號{} ?????我不喜歡它,因爲它似乎是一個序列被考慮。此外,我的代碼還會在{}球拍中的一條指令和另一條指令之間編譯,而不會插入分號。爲什麼????

+0

對不起AndryC錯誤的標題... Thankyou糾正它:) – Andry 2011-02-11 19:10:50

+0

對不起再次爲我的錯誤...謝謝你nyinyithann糾正... – Andry 2011-02-11 19:42:47

回答

2

關於2),構造函數的主體與典型函數的主體不同 - 它具有受限的語法形式,並且在{ }部分中,它只能包含對父構造函數的調用和字段的賦值類似於記錄建設)。在定義普通成員時,即使您想要(即,在此上下文中,大括號不是可選的,但它們被禁止),您也不能將單個表達式包裝在{ }中。

3

你寫(重點煤礦):

隱類。這些類有一個構造函數只有,並且在類的第一行中,有必要使用let綁定來定義爲其賦值的所有內部變量。

這實際上並不正確 - 您可以使用隱式語法來定義具有多個構造函數的類。實際上,我認爲幾乎總是使用隱式類語法是一個好主意(因爲它使得聲明更簡單)。隱類有一個主構造這是你得到隱含的一個 - 這個構造應採取的參數數量最多(但它可以是私有的):

type Foo(a:int, b:int) = 
    do printfn "hello"   // additional constructor code 
    member x.Multiple = a * b // some members 
    new(x:int) = Foo(x, x)  // additional constructor 

爲了使構造私有的,你可以寫

type Foo private (a:int, b:int) = 
    ... 

然後你可以使用主構造只是作爲一個很好的方式來初始化所有字段。