【问题标题】:How to define type member constant in F#?如何在 F# 中定义类型成员常量?
【发布时间】:2010-03-08 07:46:39
【问题描述】:

在 C# 中,可以像这样定义类型成员常量:

class Foo { public const int Bar = 600; }

IL 看起来像这样。

.field public static literal int32 Bar = int32(600)

如何在 Visual F# / FSharp 中做同样的事情?

我试过没有用:

[<Sealed>]
 type Foo() =

    [<Literal>]
    let Bar = 600

【问题讨论】:

标签: .net f# constants


【解决方案1】:

我用 F# 编译器做了几个实验,下面是我的一些观察。如果要创建 IL 文字,则需要将标记为 Literal 的值放在模块内。比如这样:

module Constants = 
  [<Literal>]
  let Num = 1

作为旁注,我快速搜索了 F# 规范,似乎文字对于模式匹配非常有用,因为您可以将它们用作模式(只要它们以大写字母开头) :

open Constants
match 1 with
| Num -> "1"
| _ -> "other"

现在,问题是,为什么将 Literal 放在类型声明中时,它的行为不符合您的预期。我认为原因是 F# 类型声明中的 let 声明不能是公共的,并且只能在类/类型中可见。我相信当您使用 C# 和 F# 内联文字值时,这也是在类型声明中完成的。但是,由于文字不能公开,因此没有理由生成 literal IL 字段,因为没有人可以访问它。

【讨论】:

  • 在 C# 中,文字将内联在字节码中,但 const 字段仍将存在以供其他类型使用。
  • 是 - 在 F# 中,如果文字是公共的(例如在模块中)并且可以被某人使用,则将生成 field;如果它只在类中可见,那么生成字节码是没有意义的,因为其他类型无论如何都不能使用它。
【解决方案2】:

我不确定这是否可行。事实上,我什至不认为你可以创建不可变的公共字段,更不用说常量了。

【讨论】:

  • 我相信您可以使用val 声明和显式初始化在使用new() 编写的构造函数中创建公共不可变字段,但这不适用于常量,因为val 字段已初始化在构造函数中。
  • @Tomas - 我认为您会发现您的建议实际上会导致定义一个属性,而不是一个字段。但是,使用 val mutable 确实会导致可变字段。
  • 你是对的。 public val 产生一个带有私有字段的属性(动机是禁止该类的可能 C# 用户修改应该是不可变的字段)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
  • 2021-11-02
相关资源
最近更新 更多