2

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

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

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

但是,即使我使用了“as self”,为什么还要使用“member this.Something”语法呢?如果我只写“member Something”,为什么它会给我一个错误?我错过了什么?

保重,克尔

4

3 回答 3

2

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

关于为什么需要this.在成员声明中,我认为这是一个自然的选择,因为在 F# 类中,您通常也有 let 边界和静态方法。默认self设置会导致混淆和误用。

这是一个as selfMSDN中使用的示例,这在 IMO 中并不常见:

type MyClass2(dataIn) as self =
   let data = dataIn
   do
       self.PrintMessage()
   member this.PrintMessage() =
       printf "Creating MyClass2 with Data %d" data
于 2012-08-26T10:43:22.993 回答
2

听起来您已经掌握了全局“as xxx”和成员“yyy”之间的所有区别。实例绑定整理。所以我想你的答案必须是“设计”。

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

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

但我们当然已经冒险进入了品味和意见的领域。

于 2012-08-26T13:29:42.437 回答
0

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

于 2012-08-26T22:00:52.797 回答