编辑:我无法理解为什么在AnyCacheable类中的where子句 - where U.CacheType == T
中,Swift不会将该语句视为约束,而只是将T设置为{{1 }}。当事情不明显时,类型推断是最糟糕的:-)
我正在尝试按照here -
讨论Swift的类型擦除具体如下代码:
U.CacheType
如果我创建protocol Cacheable {
associatedtype CacheType
func decode(_ data:Data) ->CacheType?
func encode()->Data?
}
extension String:Cacheable {
func decode(_ data:Data)->String? {
let string = String(data: data, encoding: .utf8)
return string
}
func encode()->Data? {
return data(using: .utf8)
}
}
class AnyCacheable<T>:Cacheable {
private let _encode:()->Data?
private let _decode:(_ data:Data)->T?
init<U:Cacheable>(_ cacheable:U) where U.CacheType == T {
self._encode = cacheable.encode
self._decode = cacheable.decode
}
func decode(_ data:Data)->T? {
return _decode(data)
}
func encode() -> Data? {
return _encode()
}
}
的新实例作为 -
AnyCacheable
我不需要像let cacheable:AnyCacheable = AnyCacheable("Swift")
Swift如何推断'T'的具体类型?从初始化程序 -
let cacheable:AnyCacheable = AnyCacheable<String>("Swift")
我可以看到Swift可以从初始化器参数推断出'U'的类型(在本例中是String类型)。在where子句'T'在rhs上。那么这个表达式如何评估为真呢?
答案 0 :(得分:0)
String是一个Cacheable,它的decode
返回一个String,因此它的关联类型CacheType必须是String。
使用String初始化AnyCacheable,根据需要可以使用Cacheable;所以它的U是String。但是U.CacheType
是T.所以T是String。
要知道是这样,请将String的Cacheable的定义更改为:
extension String:Cacheable {
func decode(_ data:Data)->Int? {
return 42
}
func encode()->Data? {
return data(using: .utf8)
}
}
现在编译你的代码并查看你在行中获得的类型
let cacheable:AnyCacheable = AnyCacheable("Swift")
是AnyCacheable<Int>
。