我正在研究F#的基础知识,我仍然处于不确定可能性或可用性的地步.我认为应该有更好的方法来做到这一点:
我正在查看使用此代码添加类型保护的常见演示场景
type CustomerId = CustomerId of int
type OrderId = OrderId of int
Run Code Online (Sandbox Code Playgroud)
在某些时候,我有需要解包整数的持久性代码:
dbcmd.Execute(CID = ???, OID = ???)
Run Code Online (Sandbox Code Playgroud)
选项A:笨重但有效
dbcmd.Execute(CID = match CustomerId with (CustomerId cid) -> cid, OID = match OrderId with (OrderId oid) -> oid)
Run Code Online (Sandbox Code Playgroud)
选项B源自F#中单个案例区分联合的简明模式匹配中的答案
这需要2行,如果有4或5件事要解开,我开始真的不喜欢let
声明左右之间的"距离" - 我最终可能会输入一些乱序
let (CustomerId cid, OrderId oid) = (CustomerId, OrderId)
dbcmd.Execute(CID = cid, OrderId = oid)
Run Code Online (Sandbox Code Playgroud)
选项C:如果没有更好的选择,这可能是我更喜欢的.很明显,但消耗的垂直空间比我希望的要多
let (CustomerId cid) = CustomerId
let (OrderId oid) = OrderId
dbcmd.Execute(CID = cid, OrderId = oid)
Run Code Online (Sandbox Code Playgroud)
选项D:这是我希望存在的一种.这实际上不起作用,因为这是包装的语法,而不是解包,但你明白了
dbcmd.Execute(CID = (CustomerId id), OID = (OrderId id))
Run Code Online (Sandbox Code Playgroud)
是否存在类似于选项D的简洁语法?
我通常使用其中一种选项,直观地在它们之间进行选择.大多数情况下,我更喜欢选项1,但如果我需要将构造函数设为私有,则它不起作用.
你可以这样做,因为函数参数不必只是普通的标识符,它们也可以是模式.
let f (CustomerId cid) (OrderId oid) =
let cmd = ...
cmd.Execute( cid, oid )
Run Code Online (Sandbox Code Playgroud)
type CustomerId = CustomerId of int
with static member toInt (CustomerId id) = id
cmd.Execute( CustomerId.toInt cid, ... )
Run Code Online (Sandbox Code Playgroud)
type CustomerId = CustomerId of int
with member this.asInt = match this with (CustomerId id) -> id
cmd.Execute( cid.asInt, ... )
Run Code Online (Sandbox Code Playgroud)