需要帮助理解F#类语法

时间:2012-08-26 10:11:49

标签: f#

这是关于F#类语法的一个非常基本的问题。这里有一些代码来说明我的问题。

type AClass() as self =
    member this.Something = printfn "Hello"

基本上从我所读到的" as self"将为当前实例创建一个名称,该名称可以在整个类中使用(例如"这个"在C#或Java中)。但是"会员这个。东西"将做同样的事情,只是范围仅限于方法体。我想我可以看到你什么时候使用哪种语法。 " as self"如果你在构造函数中需要它,可以使用一个,如果你在构造函数中不需要它,你可以使用另一个。

但为什么我必须使用"会员。这个"语法,即使我使用" as self"一?如果我只是写#34;成员某事"?为什么它会给我一个错误?我错过了什么?

保重, 克尔

3 个答案:

答案 0 :(得分:2)

as self的范围是整个班级,而this.Something的范围只是一个单独的方法。您通常不需要as self,因为使用this.Something就足够了。

关于你在成员声明中需要this.的原因,我认为这是一个很自然的选择,因为在F#类中你经常也有边界和静态方法。将self作为默认值会导致混淆和误用。

以下是MSDN中使用as self的示例,这不是常见的IMO:

type MyClass2(dataIn) as self =
   let data = dataIn
   do
       self.PrintMessage()
   member this.PrintMessage() =
       printf "Creating MyClass2 with Data %d" data

答案 1 :(得分:2)

听起来你在全球'作为xxx'和成员'yyy'之间存在所有差异。实例绑定整理出来。所以我想你答案的答案必须是“按设计”。

人们会争辩说这种“按设计”选择背后有一种刻意的理性,但经过4年F#编程,我最喜欢的语言,我个人认为它在任何方面都没有帮助。

我怀疑语言需要显式实例绑定变量的真正原因是因为它更接近地反映了底层的.NET CIL实现。也就是说,像C#这样的语言将“this”绑定到类定义的实例作为特征。在引擎盖下,使用Call和CallVirt操作码以相同的方式调用类的静态方法和实例方法,其中在实例方法的情况下,将“this”的地址作为调用的第一个参数加载。

但我们当然冒险进入品味和观点领域。

答案 2 :(得分:0)

我认为这根本不重复。 self对整个班级的可见性是F#主要构造者“智能”编译的副产品。构造函数的参数/绑定可以隐式编译到本地和成员(类级)字段。 as identifier语法仅仅促进了该突变上下文中的this引用。我冒昧地猜测,如果未使用,它会被编译掉。否则,您所做的就是存储对this的额外引用作为成员字段(在其他语言中看起来很奇怪,例如C#)。