我有一个以下 F# enum
type DataType = AUCTION|TRANSACTION
Run Code Online (Sandbox Code Playgroud)
我想用DataType作为参数的函数,因此该参数的值被限制在串AUCTION并TRANSACTION,
是可以将此项中的项目转换enum为string,还是有更好的方法来将参数的值限制为一组string?
The*_*ght 11
首先,正如几个人在评论中提到的那样,你定义的类型不是枚举,它是一个被歧视的联盟.
枚举实际上只是给定整数的标签,在F#中,使用以下语法声明:
type DataType =
|Auction = 1
|Transaction = 2
Run Code Online (Sandbox Code Playgroud)
使用此语法,您在值和关联的整数之间建立了关系,您可以使用整数来获取枚举的值,例如
let transaction = enum<DataType>(2) // Transaction
Run Code Online (Sandbox Code Playgroud)
请注意enum<DataType>(3537),即使我们没有定义这种情况,也没有什么能阻止你说.
有关枚举的更多详细信息,请参阅:https://msdn.microsoft.com/en-us/library/dd233216.aspx
受歧视的联盟比枚举更灵活.我们来看看你的:
type DataType =
|Auction
|Transaction
Run Code Online (Sandbox Code Playgroud)
这个版本现在实际上是一个带有两个案例标识符的标准.NET类:Auction和Transaction.你可以认为拍卖和交易的两个类型构造的DataType.
受歧视的联盟不仅限于简单的案例,您可以存储其他数据,例如
type DataType =
/// An auction with a list of bids
|Auction of Bid list
/// A transaction with some price in GBP
|Transaction of decimal<GBP>
Run Code Online (Sandbox Code Playgroud)
对于Disciminated Unions,没有与整数的隐式关系,如果我们想要构造一个特定的情况,我们必须使用适当的case标识符.
例如 let auction = Auction (bidlist)
有关歧视联盟的更多详细信息,请参阅:https://msdn.microsoft.com/en-us/library/dd233226.aspx
在这两种情况下,可以使用模式匹配来实现针对每种情况转换为特定字符串.
对于被歧视的联盟:
let datatypeToString datatype =
match datatype with
|Auction -> "AUCTION"
|Transaction -> "TRANSACTION"
Run Code Online (Sandbox Code Playgroud)
对于枚举:
let datatypeToString datatype =
match datatype with
|DataType.Auction -> "AUCTION"
|DataType.Transaction -> "TRANSACTION"
Run Code Online (Sandbox Code Playgroud)
请注意,当您使用Enumerations时,F#会给您一个编译器警告,告诉您模式匹配的情况不完整.这是因为Enumerations只是ints并且int除了1和2之外还有很多s,这意味着匹配情况并非详尽无遗.
因此,我建议你坚持使用Discriminated Unions并保持详尽的模式匹配.
PS.如果您想在另一个方向走,从string到DataType,我建议使用tryCreateDataType功能,会是这个样子:
let tryCreateDataType str =
match str with
|"AUCTION" -> Some Auction
|"TRANSACTION" -> Some Transaction
|_ -> None
Run Code Online (Sandbox Code Playgroud)
这将返回一个Option,因此它将允许您安全地匹配正在成功的函数或由于无效字符串而失败.
| 归档时间: |
|
| 查看次数: |
1157 次 |
| 最近记录: |