Swift - 具有实现通用协议的值的 Typealias 字典

Posted

技术标签:

【中文标题】Swift - 具有实现通用协议的值的 Typealias 字典【英文标题】:Swift - Typealias dictionary with value that implements a generic protocol 【发布时间】:2014-09-19 15:53:12 【问题描述】:

我想为实现 Equatable 协议的对象/结构的字符串键和值的字典键入别名。所以我写了这行代码,但它给了我错误,我不知道如何继续修复。

typealias Storage = [String: Equatable]

我想使用类型 [String: E​​quatable] 作为协议中的变量,例如:

protocol StorageModel 
    var storage: Storage  get set 
    init(storage: Storage)

错误:

Protocol 'Equatable' 只能用作通用约束,因为 它有 Self 或关联的类型要求

任何人都可以提出解决方案吗?

【问题讨论】:

【参考方案1】:

一般来说不需要protocol标签,protocol名是一等类型名,可以直接使用:

typealias Storage = [String:Equatable]

在这种情况下,错误告诉您的是,因为 Equatable 包含 func == (lhs:Self, rhs:Self) -> Bool,特别是 lhs:Self,所以除了作为泛型的约束之外,不能使用 Equatable:

class Generic<T:Equatable>  ... 

如果没有更多关于您想要实现的目标以及您如何尝试使用 StorageModel 的详细信息,我能想到的最好办法是:

protocol Matches 
    typealias T
    func matches(t:T) -> Bool


protocol StorageModel 
    typealias T
    var storage: [String:T]  get set 
    init(storage:[String:T])


extension Int : Matches 
    func matches(target:Int) -> Bool 
        return self == target
    


class MyClass <T:Matches> 
    var model = [String:T]()



另一种可能性是使用泛型而不是协议:

class StorageModel <T:Equatable> 
    var storage: [String:T]

    init(storage:[String:T]) 
        self.storage = storage
    

从那里你需要做一些研究,深入研究 Swift 手册,做一些谷歌搜索,看看什么能解决你的问题。

【讨论】:

换句话说,我应该如何实现这一目标? 由于 Equatable 的定义方式,如果不定义自己的看起来很像 Equatable 的协议,我认为你不能这样做,即使那样我认为你也会遇到同样的问题。您最好的选择可能是定义一个定义 equals 方法并使用它的新协议。 我刚刚更新了这个问题,你能帮我解决一下吗?

以上是关于Swift - 具有实现通用协议的值的 Typealias 字典的主要内容,如果未能解决你的问题,请参考以下文章

Swift 5:在使用协议实现 Equatable 的结构上实现通用数组操作

具有特定键和值的通用类型

无法将协议的通用关联类型的值转换为预期的参数类型

Swift 协议扩展实现另一个具有共享关联类型的协议

NSManagedObject 子类的 Swift 链接器错误实现具有所需初始化的协议

具有来自 .tfvars 的值的 terraform for_each 实现