Not every language with a static type system is as strong as Swift. This is made possible by Swift features such as phantom types, generic type extensions, and enumerations with associated types. This week we will learn how to use phantom types to create type-safe APIs.
The basics
โ , , , . API. .
struct Identifier<Holder> {
let value: Int
}
Identifier Holder. , Holder Identifier. . .
struct User {
let id: Identifier<Self>
}
struct Product {
let id: Identifier<Self>
}
let product = Product(id: .init(value: 1))
let user = User(id: .init(value: 1))
user.id == product.id
User () Product (), Identifier. 1 user product. , Swift :
ยซ==ยป Identifier-User Identifier-Product.
, ยซยป ยซยป. . Swift . , Swift .
func fetch(_ product: Identifier<Product>) -> Product? {
// return product by id
}
fetch(user.id)
HealthKit
. . , HealthKit Apple Watch. , Apple Health.
import HealthKit
let store = HKHealthStore()
let bodyMass = HKQuantityType.quantityType(
forIdentifier: HKQuantityTypeIdentifier.bodyMass
)!
let query = HKStatisticsQuery(
quantityType: bodyMass,
quantitySamplePredicate: nil,
options: .discreteAverage
) { _, statistics, _ in
let average = statistics?.averageQuantity()
let mass = average?.doubleValue(for: .meter())
}
store.execute(query)
Apple Health. . , , . , API.
enum Distance {
case mile
case meter
}
enum Mass {
case pound
case gram
case ounce
}
struct Statistics<Unit> {
let value: Double
}
extension Statistics where Unit == Mass {
func convert(to unit: Mass) -> Double {
}
}
extension Statistics where Unit == Distance {
func convert(to unit: Distance) -> Double {
}
}
let weight = Statistics<Mass>(value: 75)
weight.convert(to: Distance.meter)
HealthKit, API . Mass () Distance (), . , Swift , :
Distance Mass.
, Swift. , . API . , . Twitter . !
"iOS Developer. Professional", - : "Machine Learning iOS CoreML CreateML".