【问题标题】:How to define an enum constant using the underlying value如何使用基础值定义枚举常量
【发布时间】:2013-01-09 23:16:40
【问题描述】:

这个 C# 的 F# 等价物是什么:

const MyEnum None = (MyEnum)1;

这不起作用:

[<Literal>]
let None : MyEnum = enum 1 //ERROR: not a valid constant expression

虽然奇怪的是,在属性构造函数中是可以的:

[<MyAttribute(enum 1)>]
type T = class end

这种差异似乎很奇怪。

更新

这已在 v3.1 中得到修复并按预期工作。

【问题讨论】:

  • 是的,这很奇怪,如果它在 F# *cough* 的某些未来版本中得到修复,我不会感到惊讶。

标签: f# enums constants


【解决方案1】:

我相信观察到的编译器行为是故意的,并且完全符合 F# Language Spec $10.2.2: 定义的具有 [&lt;Literal&gt;] 属性的值的限制

右侧的表达式必须是 literal 常量表达式,由以下任一组成:

  • 一个简单的常量表达式,除了 ()、本机整数文字、无符号本机整数 字面量、字节数组字面量、BigInteger 字面量和用户定义的数字字面量。 —或者—
  • 对另一个字面量的引用

考虑

type MyEnum =
| Case1 = 1
| Case2 = 2

然后

[<Literal>]
let Valid: MyEnum = MyEnum.Case1 // Literal enumeration case on the right

会很高兴地编译,但是

[<Literal>]
let Invalid: MyEnum = enum<MyEnum>(1) // Expression on the right
                                      // generating constant value, which
                                      // potentially might be completely off
                                      // legit MyEnum cases

不会,尽管在 [&lt;Literal&gt;] 上下文之外,两个语句都将编译成完全相同的 IL。

假设 [&lt;Literal&gt;] 属性是使 C# const 等效的唯一 F# 方法,定义枚举文字值的唯一选项将是在 let 右侧使用适当类型的文字枚举大小写。

【讨论】:

  • 它在属性构造函数中是有效的,这让我感到困惑。我希望属性参数和文字有类似的规则。 F# 规范对此事保持沉默,但 C# 规范 states 属性参数 (E) 必须是:常量、System.Type 对象或 E 的一维数组...然而,enum 函数在这种情况下有效。
  • 简而言之,enum 1 在属性构造函数中被视为常量 (?),但在定义文字时则不然。错误?
  • 也许还值得注意,enum 只是转发到unboxPrim(通过EnumOfValue),它的定义是:let inline unboxPrim&lt;'T&gt;(x:obj) = (# "unbox.any !0" type ('T) x : 'T #) ...肯定是一个神奇的功能。
【解决方案2】:

差异是由于 C# (MyEnum)0 确实是一个文字,但 F# enumint32 -&gt; 'T 类型的函数。
我相信 F# 团队为这个构造添加特殊处理并不难,但不幸的是它还没有。

尽管如此,有一种方法可以满足您的需要,但仅限于 0 值:

type MyEnum =
    | None = 0
    | Foo = 1

[<Literal>]
let X = MyEnum()

【讨论】:

  • 有趣。我随意选择了0 作为我的例子。 enum 可以在属性中使用,但不能在常量中使用,这没什么意义。
  • @Daniel 您是否有一个示例,您需要 Literal 的数值,但不能使用枚举值?
  • the example (on fpish) 激发了这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-29
  • 2014-09-10
相关资源
最近更新 更多