2011-02-15 189 views
7

我正在嘗試創建一個複雜類型,並且需要在構建時執行一些操作。 於是我開始寫我的代碼:試圖將一個用於或轉讓別的東西編譯器發瘋時瞭解F#類型的構造函數

type public MyType = 
    val private myvar: int 
    val private myvar2: string 
    (* ...Some val declarations... *) 
    new() = { 
     (* The default ctor makes something *) 
    } 
    new (ctorpar: AnotherType) = { 
     myvar = 1; 
     myvar2 = "Hello"; 
     (* Other assignments in the form var = val *) 
     (* Here I would like to start a cycle in order *) 
     for i in ctorpar.array do 
     (* Do something *) (* ERROR *) 
    } 

嘛。 我假設以下內容:新的語法遵循計算表達式之一,或更好,新是一個計算表達式(我暗示這是因爲大括號和從一個指令到另一個指令的分號)。在這種情況下,對於構造函數計算表達式,僅可以分配賦值。

所以,請你能不能回答我:

1)是我扣是否正確? (關於計算表達式和類型的構造函數)。

2)我應該怎麼做我是否需要放置鉸接式指令集在構造函數中執行????那麼你知道,有時候有必要在施工時執行一個動作,它可能涉及從一個循環到所有可能性的一切。

但是,編譯生氣反正...

感謝KVD我明白,我必須做以下可能性:

type public MyType = 
    val private myvar: int 
    val private myvar2: string 
    (* ...Some val declarations... *) 
    new() = { 
     (* The default ctor makes something *) 
    } 
    new (ctorpar: AnotherType) = 
     for i in ctorpar.ACollection do 
     (* Something *) 
     { 
     myvar = 1; 
     myvar2 = "Hello"; 
     } 

嗯,我很抱歉,但是這並不能幫助我因爲F#編譯器告訴我:

對象構造不能直接使用 嘗試/使用,並嘗試/對象的最終前 初始化。這個 包括構造函數,例如'for x in ...',可以詳細說明這些構造的用法。這是Common IL強加的限制 。

OK,如果這個問題是在做之前對象initalization東西,這聽起來是正確的,那麼讓我們做到這一點後:

的:

type public MyType = 
    val mutable private myvar: int 
    val mutable private myvar2: string 
    (* ...Some val declarations... *) 
    new() = { 
     (* The default ctor makes something *) 
    } 
    new (ctorpar: AnotherType) = 
     { 
     myvar = 1; 
     myvar2 = "Hello"; 
     } 
     then 
     for i in ctorpar.ACollection do 
     (* Something *) 
     myvar <- 10 

的故障再次受挫值或構造函數'myvar'是 未定義。

我應該怎麼辦???? 看起來,之後,它不識別我的類中的元素,它似乎是正確的,因爲它需要一個標識符來聲明使用self或this的成員時......在這裏它沒有自引用,並且正確地告訴我:「你想要得到我不能給你的東西!!!!!!」

回答

13
  1. 不,您的推論是不正確的。花括號更像是一個記錄構造表達式,它只能包含字段賦值。 除了爲大括號內的每個字段賦值以外,您無法執行任何操作。

  2. 您可以將語句放在字段賦值之前(即,在大括號之前)。然後,如果您希望以後執行其它語句,你需要使用then關鍵字:

    type public MyType = 
        val private myvar: int 
        val private myvar2: string 
    
        new() = 
        for i in 1 .. 10 do 
         printfn "Before field assignments %i" i 
        { myvar = 1; myvar2 = "test" } 
        then 
         for i in 1 .. 10 do 
         printfn "After field assignments %i" i 
    

編輯

關於你的新問題,你可以使用new (ctorpar:AnotherType) as this = ...,然後this.myvar <- 10

+0

kvb非常感謝你,你真的很清楚我的一切,不僅僅是我剛剛問過的,而是更多。現在它使感知。非常感謝你。 – Andry 2011-02-15 20:24:51

+0

「then」關鍵字在文檔中出現在哪裏?它絕對有效,但我認爲我以前從未見過它。 – 2011-02-15 20:37:14

9

來自kvb的答案很好,併爲您提供了所有需要的信息:-)。

我只是建議使用隱式語法,其中主構造函數緊跟在類型名稱後面。這使得很多事情變得更加容易:

type MyType(n:int, s:string) = 
    do 
    // Run before fields initialized (they aren't accessible here) 
    for i in 1 .. 10 do 
     printfn "Before field assignments %i" i 
    // Initialize fields (accessible from now on) 
    let myvar = n 
    let myvar2 = s 
    do // Run after fields initialized - you can use them here 
    for i in 1 .. 10 do 
     printfn "After field assignments %i" i 

    // You can add multiple constructors too: 
    new() = MyType(0, "hi") 
    member x.Foo = 0