F#中的强类型ID?
我的应用程序中有两种实体:客户和产品。它们各自在数据库级别由UUID标识 在我的F#代码中,这可以用F#中的强类型ID?,f#,F#,我的应用程序中有两种实体:客户和产品。它们各自在数据库级别由UUID标识 在我的F#代码中,这可以用System.Guid表示 为了便于阅读,我添加了如下类型: open System type CustomerId = Guid type ProductId = Guid 但是,这并不妨碍我将ProductId用作CustomerId,反之亦然 我想出了一个办法来防止这种情况: open System [<Struct>] type ProductId = {
System.Guid
表示
为了便于阅读,我添加了如下类型:
open System
type CustomerId = Guid
type ProductId = Guid
但是,这并不妨碍我将ProductId
用作CustomerId
,反之亦然
我想出了一个办法来防止这种情况:
open System
[<Struct>]
type ProductId =
{
Product : Guid
}
[<Struct>]
type CustomerId =
{
Customer : Guid
}
但它增加了类型安全性:
// let customerId : CustomerId = productId // Type error
我想知道还有什么其他的方法 您可以使用以下类型:
开放系统
[]
类型ProductId=Guid的ProductId
[]
类型CustomerId=Guid的CustomerId
让productId=productId(Guid.NewGuid())
通常,我们会将一些方便的助手方法/属性直接添加到类型中:
[<Struct>]
type ProductId = private ProductId of Guid with
static member Create () = ProductId (Guid.NewGuid())
member this.Value = let (ProductId i) = this in i
[<Struct>]
type CustomerId = private CustomerId of Guid with
static member Create () = CustomerId (Guid.NewGuid())
member this.Value = let (CustomerId i) = this in i
let productId = ProductId.Create ()
productId.Value |> printfn "%A"
[]
类型ProductId=Guid为的私有ProductId,带有
静态成员Create()=ProductId(Guid.NewGuid())
成员this.Value=let(ProductId i)=i中的this
[]
类型CustomerId=Guid为的私有CustomerId,带有
静态成员Create()=CustomerId(Guid.NewGuid())
成员this.Value=let(CustomerId i)=i中的this
让productId=productId.Create()
productId.Value |>printfn“%A”
另一种不太常见但值得一提的方法是使用所谓的幻影类型。这个想法是,您将有一个通用的包装器id这是非常有趣的。与imho合作,单案例工会已经相当麻烦,因此探索选项很好。但您必须在这里使用幻影类型吗?假设您希望它成为您现有类型的IDtype Person={Name:string;Age:int}
,您不能只说Let fetchPerson(ID:ID):async=.
?我制作了一个:type ID=| ID'B静态成员nw B=ID B成员this.Value=将其与ID-ID->ID匹配,以便您可以在字符串之间进行选择,GUID或int64,然后使用如下别名:type PersonId=ID和Person={ID:PersonId Name:string}//等。
open System
[<Struct>]
type ProductId = ProductId of Guid
[<Struct>]
type CustomerId = CustomerId of Guid
let productId = ProductId (Guid.NewGuid())
[<Struct>]
type ProductId = private ProductId of Guid with
static member Create () = ProductId (Guid.NewGuid())
member this.Value = let (ProductId i) = this in i
[<Struct>]
type CustomerId = private CustomerId of Guid with
static member Create () = CustomerId (Guid.NewGuid())
member this.Value = let (CustomerId i) = this in i
let productId = ProductId.Create ()
productId.Value |> printfn "%A"
[<Struct>]
type ID<'T> = ID of System.Guid
type CustomerID = interface end
type ProductID = interface end
let newCustomerID () : ID<CustomerID> = ID(System.Guid.NewGuid())
let newProductID () : ID<ProductID> = ID(System.Guid.NewGuid())
let printID (ID g) = printfn "%s" (g.ToString())
let ci = newCustomerID ()
let pi = newProductID ()
printID ci
printID pi
ci = pi // Type mismatch. Expecting a 'ID<CustomerID>' but given a 'ID<ProductID>'