我想编写一个带有 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
但是编译器仍然在
typeof<^TEnum>
行提示:“错误 FS3156:意外的标记 '>' 或不完整的表达式”。我究竟做错了什么?我怎么能写这个函数?
最佳答案
您只需要在“帽子”符号 ˆ
和 <
之间留一个空格,如下所示:
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
因为在这种情况下会自动推断静态约束,所以真正需要编写“帽子”的唯一地方是手动编写静态约束。
关于generics - F# 中的严格通用枚举转换,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34102084/