[英]Swift Type Inference and Protocols with Associated Types
编辑 :我不明白为什么在下面的where子句中-AnyCacheable类中的where U.CacheType == T
Swift不会将该语句视为约束,而只是将T设置为U.CacheType
。 当事情不那么明显时,类型推断是最糟糕的:-)
我正在尝试遵循此处讨论的Swift的Type擦除-
具体来说,下面的代码:
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")
我不需要显式指定'T'的具体类型,如let cacheable:AnyCacheable = AnyCacheable<String>("Swift")
Swift如何推断'T'的具体类型? 从初始化器-
init<U:Cacheable>(_ cacheable:U) where U.CacheType == T {
self._encode = cacheable.encode
self._decode = cacheable.decode
}
我可以看到Swift可以从初始化参数中推断出'U'的类型(在这种情况下为String类型)。 在where子句中,“ T”在rhs上。 那么该表达式如何评估为真?
String是可缓存的,并且其decode
返回String,因此其关联类型CacheType必须为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>
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.