Swift 类型推断和关联类型协议(protocol)

标签 swift generics protocols swift-protocols

编辑:我不明白为什么在下面的 where 子句中 - where U.CacheType == T在 AnyCacheable 类中,Swift 不会将该语句视为约束,而只是将 T 设置为 U.CacheType 。当事情不明显时,类型推断是最糟糕的:-)

<小时/>

我正在尝试遵循讨论的 Swift 类型删除 here -

具体代码如下:

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 可以从初始化参数(在本例中为 String 类型)推断出“U”的类型。在 where 子句中,'T' 位于 rhs 上。那么该表达式如何计算为 true 呢?

最佳答案

字符串是可缓存的,其 decode返回一个String,所以它的关联类型CacheType必须是String。

AnyCacheable用String初始化,根据需要是一个Cacheable;所以它的 U 是 String。但是U.CacheType是 T。所以 T 是字符串。

<小时/>

要看到是这样,将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> .

关于Swift 类型推断和关联类型协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48649946/

相关文章:

ios - 为什么 UIScrollView 的内容不居中?

swift - 如何在 SceneKit 中绘制箭头?

ios - 在文本中添加无限行(SwiftUI)

vb.net - List(Of T).ForEach 中 Visual Basic 中的 Action(Of T)

c# - 类对泛型类型参数所做的事情的术语

swift - 无法分配给类型的不可变表达式...但使用协议(protocol)

swift - 我不明白我的代码中的 Property 'self.heading' not initialized at super.init 调用错误

swift - 泛型方法中 T 和 Self 的区别

ios - 为一个或另一个扩展具有多个约束的协议(protocol) - Swift

protocols - 金融机构的 FIX 协议(protocol)是什么?