如何使用基础值定义一个枚举常量
什么是这个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
这种差异似乎很奇怪。
UPDATE
这已在v3.1中修复,并按预期工作。
我相信观察到的编译器行为是有意的,并且完全符合由F#Language Spec $ 10.2.2定义的具有[<Literal>]
属性值的限制:
右侧表达式必须是由以下任一项组成的文字常量表达式:
考虑
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
不会,虽然在[<Literal>]
上下文中,两个语句都会编译成完全相同的IL。
假设[<Literal>]
属性是使C# const
等价的唯一F#方法,定义枚举文字值的唯一选择是使用let
右侧的正确类型的文字枚举大小写。
这种差异是由C# (MyEnum)0
确实是一个文字,但F# enum
是类型为int32 -> 'T
的函数引起的。
我相信F#团队为这个构造添加特殊处理并不困难,但不幸的是它还没有。
尽管如此,有一种方法可以实现你所需要的,但只有0
值:
type MyEnum =
| None = 0
| Foo = 1
[<Literal>]
let X = MyEnum()
链接地址: http://www.djcxy.com/p/11761.html
上一篇: How to define an enum constant using the underlying value