【发布时间】:2013-03-27 14:36:51
【问题描述】:
F# 具有称为"Type extension" 的功能,它使开发人员能够扩展现有类型。 有两种类型的扩展:内在扩展和可选扩展。第一个类似于 C# 中的部分类型,第二个类似于方法扩展(但更强大)。
要使用内部扩展,我们应该将两个声明放在同一个文件中。在这种情况下,编译器会将两个定义合并为一种最终类型(即这是一种类型的两个“部分”)。
问题在于这两种类型对不同的成员和值有不同的访问规则:
// SampleType.fs
// "Main" declaration
type SampleType(a: int) =
let f1 = 42
let func() = 42
[<DefaultValue>]
val mutable f2: int
member private x.f3 = 42
static member private f4 = 42
member private this.someMethod() =
// "Main" declaration has access to all values (a, f1 and func())
// as well as to all members (f2, f3, f4)
printf "a: %d, f1: %d, f2: %d, f3: %d, f4: %d, func(): %d"
a f1 this.f2 this.f3 SampleType.f4 (func())
// "Partial" declaration
type SampleType with
member private this.anotherMethod() =
// But "partial" declaration has no access to values (a, f1 and func())
// and following two lines won't compile
//printf "a: %d" a
//printf "f1: %d" f1
//printf "func(): %d" (func())
// But has access to private members (f2, f3 and f4)
printf "f2: %d, f3: %d, f4: %d"
this.f2 this.f3 SampleType.f4
我阅读了 F# 规范,但没有找到任何想法为什么 F# 编译器区分值和成员声明。
在 F# 规范的 8.6.1.3 section 中说“实例定义定义的函数和值是词法范围(因此隐式私有)到正在定义的对象。”。部分声明可以访问所有私有成员(静态和实例)。我的猜测是,“词法范围”规范的作者专门指的是“主”声明,但这种行为对我来说似乎很奇怪。
问题是:这种行为是故意的,其背后的理由是什么?
【问题讨论】:
标签: f# lexical-scope type-extension