我想编写一个带有签名int -> 'TEnum
的函数,如果目标枚举不包含输入值,它将抛出异常。这是我的第一次尝试:
let parseEnum<'TEnum when 'TEnum : enum<int>> (value : int) : 'TEnum =
let enumType = typeof<'TEnum>
if not <| Enum.IsDefined (enumType, value) then
raise <| ArgumentException (sprintf "Invalid value of %A: %d" enumType value)
enum value
编译器向我显示以下错误消息:“错误FS0001:由于在编译时无法解析类型参数,因此无法在此处使用声明的类型参数'TEnum'”(我认为这是因为enum
具有附加约束的函数。)
嗯,好吧,我明白了这个问题。我将使用statically resolved type parameter。这是我的第二次尝试:
let inline parseEnum2 (value : int) : ^TEnum =
let enumType = typeof<^TEnum>
if not <| Enum.IsDefined (enumType, value) then
raise <| ArgumentException (sprintf "Invalid value of %A: %d" enumType value)
enum value
但是编译器仍然抱怨:“错误FS3156:意外的令牌'&gt;'或“不完整的表达”在第typeof<^TEnum>
行。
我做错了什么?我怎么能写这个函数?
答案 0 :(得分:6)
你需要在帽子之间留一个空间。签署ˆ
和<
就像这样:
let enumType = typeof< ^TEnum>
事实上你不需要帽子,你可以写:
open System
let inline parseEnum2 value : 'TEnum =
let enumType = typeof<'TEnum>
if not <| Enum.IsDefined (enumType, value) then
raise <| ArgumentException (sprintf "Invalid value of %A: %d" enumType value)
enum value
因为在这种情况下会自动推断静态约束,所以当你真正需要编写“帽子”时,这是唯一的地方。是在手写静态约束时。