2011-02-11 59 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) = 
    ... 

然后你可以使用主构造只是作为一个很好的方式来初始化所有字段。