构造函数中的不可见/隐藏字段

Posted

技术标签:

【中文标题】构造函数中的不可见/隐藏字段【英文标题】:invisible / hidden field in the constructor 【发布时间】:2012-07-21 09:30:45 【问题描述】:

我正在努力通过Learn You a Haskell for Great Good,我已经到达section 8.4, "Derived Instances"。在本节中,有以下数据类型声明:

data Person = Person  firstName :: String  
                     , lastName :: String  
                     , age :: Int  
                      deriving (Eq)

尝试中

*Main> mikeD == Person firstName = "Michael", lastname = "Diamond", age = 43

我收到以下错误:

<interactive>:55:41:
`lastname' is not a (visible) field of constructor `Person'

通过将lastname 更正为lastName,我删除了错误。

问题:

在错误消息中(visible) 一词暗示我必须有可能将字段声明为隐藏/不可见。这是正确的还是不正确的?如果是,我如何将构造函数中的字段声明为隐藏,以及需要声明隐藏字段的一般场景是什么?如果您能通过给出一个简单的使用示例来解释这一点,将不胜感激。

注意:我在 LYAH 中找不到任何关于隐藏或不可见字段的参考/详细信息。

【问题讨论】:

【参考方案1】:

可以隐藏记录的字段或任何数据类型的构造函数,尽管不在声明站点。这个想法是简单地选择不从模块中导出该构造函数和/或字段,如下所示:

module MyModule (DT(C1, int, mStr)) where

data DT = C1 -- visible
              
               int :: Int, -- visible
               str :: String -- hidden
             
        | C2 -- hidden
             
               dbl :: Double, -- hidden
               mStr :: Maybe String -- visible
             

请注意,MyModule 内的所有内容仍然可以访问构造函数和所有四个字段,但在导入 MyModule 的其他模块中,只有导出的可见。

【讨论】:

“但是,不能导出给定构造函数的某些字段,而不能导出同一构造函数的其他字段。”是的。 module MyModule (DT(C1, int)) 仅导出 int,但不导出 str。另请注意,您的DT(C1) 不会导出任何字段,因此intstr 在您的代码示例中是不可见的。 @sepp2k 我不知道!我会更正我的答案,谢谢。 “仅作为函数可见,而不作为字段可见” — 也不正确。您可以使用它来更新记录。 不,没有更正。你导出它的方式并不重要。您要实现的目标(“仅作为函数可见,而不作为字段可见”)根本不可能。为此,您必须将其定义为函数,而不是字段。

以上是关于构造函数中的不可见/隐藏字段的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法让构造函数只对 C# 中的父类可见?

Kotlin:为什么构造函数参数默认具有“内部”可见性?

在构造函数本地函数c#中设置只读字段

默认情况下,将jTextArea设置为可见的false

Java 内部类可见性难题

类构造函数中的 ArrayList 字段