2011-02-15 102 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