我想坚持record
,不想回去object
。所以我想知道是否可以制作 a field
of a record private
?或做一个private member
。record
其他concrete types
的discriminated union
呢?
或者,这个要求是否违反了语言规范?
我想坚持record
,不想回去object
。所以我想知道是否可以制作 a field
of a record private
?或做一个private member
。record
其他concrete types
的discriminated union
呢?
或者,这个要求是否违反了语言规范?
不,单个字段不可能是私有的:http: //msdn.microsoft.com/en-us/library/dd233184
但是,您可以将所有字段设为私有并通过属性公开选定字段。请注意,您将需要一个 Create-function 来创建记录的实例,因为它的字段是私有的:
type MyRec =
private
{ a : int
b : int }
member x.A = x.a
member private x.Both = x.a + x.b // Members can be private
static member CreateMyRec(a, b) = { a = a; b = b }
成员可以是私有的,就像MyRec.Both
上面的属性一样。
编辑:上面的字段使 MyRec 定义的模块私有,而不是 MyRec 私有。当 F# 记录的字段被声明为 private 时,请参阅 Daniel 对 Weird 可访问性范围的回答。
这个要求的问题是记录的语言特性要求属性是公开的。例如,如果您有一个r
类型的记录,R
其中包含属性Name
和Age
写入
{ r with Age = 20 }
,编译器会将其转换为new R(r.Name, 20)
.
这个想法是with
复制所有属性(不包括您要更改的属性),因此它需要能够访问它们。为此,编译器实际上可以为每种可能的with
用途生成方法,但这可能会生成很多方法。
你偏爱唱片的原因是什么?它们有两个很好的特性 -with
关键字(无论如何你都会丢失private
成员)和结构相等(当它们具有相同的值时,两个实例是相同的)。除此之外,如果您想隐藏某些字段,类似乎更易于使用。
这是一个简单的例子(它没有实现结构相等):
type R(name:string, age:int) =
member x.Name = name
member x.WithAge(newAge) = R(name, newAge)
使用带有字段的记录似乎很好——尽管在实现文件中使用公共字段和为所有外部用户隐藏字段的F# 签名文件private
可能更有意义。这样,您可以使用实现中的功能,但仍然隐藏类型。with
我不认为这是可能的。MSDN 说:
记录字段与类的不同之处在于它们自动作为属性公开,并且用于创建和复制记录。记录构造也不同于类构造。在记录类型中,您不能定义构造函数。
“自动曝光”是回答你问题的关键。三是您不想创建新类型的任何理由吗?