问题背景:我正在同时学习功能域建模和 Swift。我正在使用的示例是在 F# 中。一个这样的例子是声明单例联合:
//F# code
type CustomerId = CustomerId of int
type OrderId = OrderId of int
let customerId = CustomerId 42
let orderId = OrderId 42
printfn "%b" (orderId = customerId) //produces a compile error
因此,在 F# 中声明本质上都是 Int
的类型安全基元似乎非常容易。
在 Swift 中,typealias
不做同样的事情:
typealias CustomerId = Int
typealias OrderId = Int
let customerId: CustomerId = 42
let orderId: OrderId = 42
customerId == orderId // true!
现在,我明白 Swift 中的所有基本类型本质上都是 struct
,但我还远未成熟到足以理解 Swift 代码库来弄清楚 Int
已创建。
有谁知道与 F# 声明等效的简单类型安全 Swift?
最佳答案
typealias
实际上只是一个别名。它不创建类型。它只是让输入别名的东西更容易。
做你想做的事情的方法是:
struct CustomerID {
let value: Int
}
struct OrderID {
let value: Int
}
如果您想要一个“裸”初始化程序(CustomerID(4)
而不是 CustomerID(value: 4)
),您可以添加:
struct CustomerID {
let value: Int
init(_ value: Int) { self.value = value }
}
因为你可能会经常这样做,所以你可以将它提取到一个协议(protocol)中
protocol Identifier {
typealias IDType
init(value: IDType)
}
extension Identifier {
init(_ value: Int) { self.init(value: value) }
}
extension CustomerID: Identifier {}
当然,如果您想要类似 = 42
的语法,您可以使用 ExpressibleByIntegerLiteral
添加类似的扩展。
您在 F# 中讨论的特定语法在 Swift 世界中通常通过其 Haskell 名称 newtype 来引用。 Swift 没有像 newtype 和 it's been discussed several times 这样易于使用的特性.在 Swift 中有几个极端情况,决定如何自动遵守协议(protocol)(尤其是需要 Self 的协议(protocol))有点复杂。但它可能有一天会实现。
您可以看到更深入的讨论 2019 AltConf talk on the subject .
关于swift - 如何基于 Int 创建一个新的类型安全的原始类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58647261/