创建具有常量值的 F# 记录类型

Creating an F# record type with a constant value

假设我有一个如此定义的记录...

type Employee = {Name : string; Salary : int}

我想要另一种 Salary 固定的类型。我希望能够说...

type Manager = {Name: string; Salary : int = 250000}

...不过好像不行

我有什么选择才能获得这种行为?

F# 记录是不可变的,因此所有字段值都是 "fixed",用您的话来说。

如果您的目标是避免在构造时指定 Salary,最简单的方法是制作 "constructor":

type Manager = {Name : string; Salary : int} with
    static member Make name =
        {Manager.Name=name; Salary=250000}

注意1.我用的是Manager.Name所以不影响Employee构建;
注意 2。此外,这种方法甚至不会阻止保留单一类型 Employee,它也将优雅地处理 Manager 的创建;只需调用该方法,例如MakeManager 为清楚起见。

static 方法不禁止某人(使用您的库的开发人员)手动创建 Manager 工资错误。有关如何防止此类创建的信息,请参阅 this answer

记录类型可以有成员,例如

  type Employee = {Name : string; Salary : int}
  type Manager =
    {Name: string; }
    member x.Salary with get() = 250000
  let manager1 = {Manager.Name = "manager1"}
  let manager2 = { manager1 with Manager.Name = "manager2"}
  let salary = manager1.Salary // fsi: val salary : int = 250000

但是如果经理是雇员,我会使用普通 类 和继承而不是记录。使用 F# 中的普通 类 非常好,并且可以通过避免 public setter 来实现不变性。

你可以给你的记录一个只读属性:

type Manager = 
    {
        Name: string
    }
     member this.Salary = 250000

FSI 示例:

> let m = { Name = "Foo" };;

val m : Manager = {Name = "Foo";}

> m.Name;;
val it : string = "Foo"
> m.Salary;;
val it : int = 250000