我有以下F#
enum
type DataType = AUCTION|TRANSACTION
我想将
DataType
用作函数的参数,以便将该参数的值限制为字符串AUCTION
和TRANSACTION
,是否有可能将此
enum
中的项目转换为string
,或者是否有更好的方法来将参数的值约束到一组string
中?
最佳答案
首先,正如一些人在评论中提到的那样,您定义的类型不是枚举,而是一个受歧视的联合。
枚举实际上只是给定整数的标签,在F#中,使用以下语法声明:
type DataType =
|Auction = 1
|Transaction = 2
使用此语法,您可以在该值和关联的整数之间建立关系,可以使用该整数获取Enumeration的值,例如
let transaction = enum<DataType>(2) // Transaction
请注意,即使我们没有定义这种情况,也没有什么可以阻止您说
enum<DataType>(3537)
。有关枚举的更多详细信息,请参见:https://msdn.microsoft.com/en-us/library/dd233216.aspx
受歧视的联盟比枚举要灵活得多。让我们来看看你的:
type DataType =
|Auction
|Transaction
现在,此版本实际上是一个标准.NET类,带有两个大小写标识符:
Auction
和Transaction
。您可以将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>
对于Disciified Union,不存在与整数的隐式关系,如果要构造特定的案例,则必须使用适当的案例标识符。
例如
let auction = Auction (bidlist)
有关歧视联盟的更多详细信息,请参见:https://msdn.microsoft.com/en-us/library/dd233226.aspx
在两种情况下,都可以使用模式匹配来转换为每种情况下的特定字符串。
对于歧视联盟:
let datatypeToString datatype =
match datatype with
|Auction -> "AUCTION"
|Transaction -> "TRANSACTION"
对于枚举:
let datatypeToString datatype =
match datatype with
|DataType.Auction -> "AUCTION"
|DataType.Transaction -> "TRANSACTION"
请注意,当您使用Enumerations时,F#将向您发出编译器警告,告知您模式匹配大小写不完整。这是因为Enumerations只是
int
,除了1和2之外还有许多int
,这意味着匹配情况并不详尽。因此,我建议您坚持歧视工会并保持详尽的模式匹配。
P.S.如果您想朝另一个方向发展,从
string
到DataType
,我建议使用tryCreateDataType
函数,该函数看起来像这样:let tryCreateDataType str =
match str with
|"AUCTION" -> Some Auction
|"TRANSACTION" -> Some Transaction
|_ -> None
这将返回
Option
,因此它将使您能够安全地将函数匹配成功或由于无效字符串而失败的函数。
关于enums - F#枚举到字符串的转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35683426/