TypeBurritoFramework
TypeBurritoFramework
是一个 Swift 微框架,它使创建包装特定情况下使用的原始类型的类型变得 快速、无样板,并允许类型检查器强制执行安全使用。
灵感
TypeBurrito
automatically receives reasonable behavior and compliance forhashValue
(Hashable
-> can be used as a dictionary key)
<
, ==
(Comparable
, but only across the same subtype)CustomStringConvertible
, meaning we can print it and use it inside String
sCustomDebugStringConvertible
TypeBurrito
is a number, then we also automatically get+
(but only across the same subtype)
-
(but only across the same subtype)+=
(but only across the same-=
(but only across the sameimport TypeBurritoFramework
TypeBurrito 声明
enum SQLQuery_Spec: TypeBurritoSpec { typealias TheTypeInsideTheBurrito = String }
typealias SQLQuery = TypeBurrito<SQLQuery_Spec>
enum Meters_Spec: TypeBurritoSpec { typealias TheTypeInsideTheBurrito = Double }
typealias Meters = TypeBurrito<Meters_Spec>
enum Inches_Spec: TypeBurritoSpec { typealias TheTypeInsideTheBurrito = Double }
typealias Inches = TypeBurrito<Inches_Spec>
实际中的 TypeBurrito
let query = SQLQuery("SELECT * FROM SwiftFrameworks")
let metersClimbedToday = Meters(40) + Meters(2)
let truth = ( Meters(1000) > Meters(34) )
var distanceLeft = Meters(987.25)
distanceLeft -= Meters(10)
let lengthOfScreenDiagonal = Inches(13)
func performSQLQuery(sqlQuery: SQLQuery){
// can only be called with a SQLQuery, not with just any String
}
以下内容如果未注释将会是编译时错误
//let _ = Meters(845.235) + Inches(332)
我们还可以使用静态函数 gatewayMap
定义 TypeBurritoSpec
,其中
static func gatewayMap(preMap: TheTypeInsideTheBurrito) -> TheTypeInsideTheBurrito
网关映射允许我们构建在允许值范围内具有 固有 限制的类型。
例如,我们可以构建一个具有自然不区分大小写的 Username
类型。这是通过有一个将任何输入转换为小写版本的 gatewayMap
来实现的。
enum _Username: TypeBurritoSpec {
typealias TheTypeInsideTheBurrito = String
static func gatewayMap(preMap: TheTypeInsideTheBurrito) -> TheTypeInsideTheBurrito{
return preMap.lowercaseString
}
}
typealias Username = TypeBurrito<_Username>
从那一刻起,我们可以确定,如果给出了一个 Username
,无论其是由小写还是大写字母构成,这都是无关紧要的。
let lowercaseSteve = Username("[email protected]")
let uppercaseSteve = Username("[email protected]")
assert(lowercaseSteve == uppercaseSteve)
当我们的值受到对我们的“心理”模型类型中固有的限制,但在底层数据类型中不具有这种限制时,gatewayMap
可以派上用场。
例子包括
URL
类型SQLCommand
类型LevelInSomeBuilding
类型我们仍然有与运行时行为而不是编译时行为相关的“类型信息”,但此信息(以及所有相关测试!)现在仅限于 gatewayMap()
函数。
FailableTypeBurrito
存在一个与 TypeBurrito
直接对应的 FailableTypeBurrito
(以及相应的 FailableTypeBurritoSpec
)。
然而,它的 gatewayMap
函数可能会返回 nil
,这将导致 FailableTypeBurrito
为 nil
。
例如
enum EnglishLettersOnlyString_Spec: FailableTypeBurritoSpec {
typealias TheTypeInsideTheBurrito = String
static func gatewayMap(preMap: TheTypeInsideTheBurrito) -> TheTypeInsideTheBurrito? {
if(preMap.stringByTrimmingCharactersInSet(NSCharacterSet.letterCharacterSet()) == "") {
return preMap
}
else{
return nil
}
}
}
typealias EnglishLettersOnlyString = FailableTypeBurrito<EnglishLettersOnlyString_Spec>
以下内容仅由英文字符组成,因此结果值为非 nil
。
let actuallyOnlyLetters = EnglishLettersOnlyString("abclaskjdf")
以下内容 不 仅由英文字符组成,因此结果值为 nil
。
let notOnlyLettes = EnglishLettersOnlyString("asdflkj12345")