Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# 是否可以将记录的字段设置为私有?还是让唱片公司的成员成为私人?_F# - Fatal编程技术网

F# 是否可以将记录的字段设置为私有?还是让唱片公司的成员成为私人?

F# 是否可以将记录的字段设置为私有?还是让唱片公司的成员成为私人?,f#,F#,我想继续使用记录,不想回到对象。因此,我想知道是否有可能将记录的字段设置为私有?或者制作记录的私人成员。其他的具体类型呢,比如区别联合 或者,这个要求是否违反了语言规范?我认为这是不可能的。MSDN说: 记录字段与类的不同之处在于它们是自动 作为属性公开,它们用于创建和复制 记录。记录结构也不同于类结构。 在记录类型中,不能定义构造函数 “自动曝光”是回答您问题的关键。你不想创建新类型的原因有三个吗 不,单个字段不可能是私有的: 但是,可以将所有字段设置为私有字段,并通过属性公开选定字段。请注意

我想继续使用
记录
,不想回到
对象
。因此,我想知道是否有可能将
记录的
字段设置为私有
?或者制作
记录的
私人成员
。其他的
具体类型
呢,比如
区别联合


或者,这个要求是否违反了语言规范?

我认为这是不可能的。MSDN说:

记录字段与类的不同之处在于它们是自动 作为属性公开,它们用于创建和复制 记录。记录结构也不同于类结构。 在记录类型中,不能定义构造函数


“自动曝光”是回答您问题的关键。你不想创建新类型的原因有三个吗

不,单个字段不可能是私有的:

但是,可以将所有字段设置为私有字段,并通过属性公开选定字段。请注意,您需要一个Create函数来创建记录的实例,因为其字段是私有的:

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私有。参见Daniel对的回答。

此要求的问题在于record的语言特性要求属性为公共属性。例如,如果您有一个类型为
r
r
记录,其属性为
Name
Age
并写入
{r with Age=20}
,编译器将其转换为
新的r(r.Name,20)

其思想是,
with
复制所有属性(不包括要更改的属性),因此它需要能够访问这些属性。为此,编译器实际上可以通过
使用为每个可能的
生成方法,但这可能会生成很多方法

你喜欢唱片的原因是什么?它们有两个很好的特性-带有
关键字的
(不管怎样,你会因为
private
成员而丢失)和结构相等(当它们具有相同的值时,两个实例是相同的)。除此之外,如果您想隐藏一些字段,类似乎更易于使用

下面是一个简单的示例(不实现结构相等):


将记录与
private
字段一起使用似乎很好——尽管在实现文件中使用公共字段和为所有外部用户隐藏字段的方法可能更有意义。通过这种方式,您可以在实现中将
等功能与
一起使用,但仍然可以隐藏类型

我从来没用过,但对我来说似乎没问题。记录“免费”为您提供结构比较,因此我可以看到它的合法用途。我觉得奇怪的是,我们能够将private放在{}前面,msdn没有说明这种用法(我在谷歌中找不到)。是的,它很奇怪,没有在MS语言参考中记录。当我看到错误消息
记录字段上不允许使用辅助功能修饰符时,我意外地发现了它。使用“type R=internal…”或“type R=private…”来提供整个表示的可访问性。
我不知道MSDN,但它在规范中。请参见中的表。当然,您可以将您想要私有的封装在较小的记录中,其中这些属性/字段是私有的,这样,您的其他属性和更高的记录级别就不需要创建函数或所有道具都是私有的。
type R(name:string, age:int) = 
  member x.Name = name
  member x.WithAge(newAge) = R(name, newAge)