如何在Swift中处理多个通用协议?

如何在Swift中处理多个通用协议?,swift,generics,protocols,Swift,Generics,Protocols,我尝试使用两个相互关联的通用协议: protocol PersistableData {} protocol DataStore: class { associatedtype DataType: PersistableData func save(data: DataType, with key: String) func retreive(from key: String) -> DataType? } protocol PersistentDataMo

我尝试使用两个相互关联的通用协议:

protocol PersistableData {}

protocol DataStore: class {
    associatedtype DataType: PersistableData

    func save(data: DataType, with key: String)

    func retreive(from key: String) -> DataType?
}

protocol PersistentDataModel {
    // Swift infers that DataType: PersistableData as DataType == DataStoreType.DataType: PersistableData
    // Setting it explicitly makes the compiler fail
    associatedtype DataType
    associatedtype DataStoreType: DataStore where DataStoreType.DataType == DataType
}

extension String: PersistableData {}

protocol StringDataStore: DataStore {
    associatedtype DataType = String
}


class Test: PersistentDataModel {
    typealias DataType = String
    typealias DataStoreType = StringDataStore
}
但是,Xcode未能编译,说明
类型“测试”不符合协议“PersistentDataModel”
,并建议
可能的预期匹配“DataStoreType”(又名“StringDataStore”)不符合“DataStore”
,而
StringDataStore
被定义为符合
DataStore


我已经阅读了一些关于泛型协议的好资源,包括和,但我找不到问题所在。

发生这种情况是因为
associatedtype的
typealias
应该是具体的,而不是抽象的

因此,对于您的情况,
StringDataStore
应该是
,而不是
协议

protocol PersistableData {}

protocol DataStore: class {
associatedtype DataType: PersistableData

    func save(data: DataType, with key: String)

    func retreive(from key: String) -> DataType?
}

protocol PersistentDataModel {
    // Swift infers that DataType: PersistableData as DataType == DataStoreType.DataType: PersistableData
    // Setting it explicitly makes the compiler fail
    associatedtype DataType
    associatedtype DataStoreType: DataStore where DataStoreType.DataType == DataType
}
extension String: PersistableData {}

class StringDataStore: DataStore {
    typealias DataType = String

    func save(data: String, with key: String) {
        //
    }

    func retreive(from key: String) -> String? {
        return nil
    }
}

class Test: PersistentDataModel {
    typealias DataType = String
    typealias DataStoreType = StringDataStore
}
但是,您可以继续使用协议,并通过在
测试
类中使用其他泛型条件来解决它:

class Test<T: StringDataStore>: PersistentDataModel where T.DataType == String {
    typealias DataStoreType = T
    typealias DataType = T.DataType
}

之所以会发生这种情况,是因为
associatedtype
typealias
应该是具体的,而不是抽象的

因此,对于您的情况,
StringDataStore
应该是
,而不是
协议

protocol PersistableData {}

protocol DataStore: class {
associatedtype DataType: PersistableData

    func save(data: DataType, with key: String)

    func retreive(from key: String) -> DataType?
}

protocol PersistentDataModel {
    // Swift infers that DataType: PersistableData as DataType == DataStoreType.DataType: PersistableData
    // Setting it explicitly makes the compiler fail
    associatedtype DataType
    associatedtype DataStoreType: DataStore where DataStoreType.DataType == DataType
}
extension String: PersistableData {}

class StringDataStore: DataStore {
    typealias DataType = String

    func save(data: String, with key: String) {
        //
    }

    func retreive(from key: String) -> String? {
        return nil
    }
}

class Test: PersistentDataModel {
    typealias DataType = String
    typealias DataStoreType = StringDataStore
}
但是,您可以继续使用协议,并通过在
测试
类中使用其他泛型条件来解决它:

class Test<T: StringDataStore>: PersistentDataModel where T.DataType == String {
    typealias DataStoreType = T
    typealias DataType = T.DataType
}

为什么有
associatedtype数据存储类型:DataStore where DataStoreType.DataType==DataType
?这可能会对您有所帮助。为什么有
associatedtype数据存储类型:DataStore where DataStoreType.DataType==DataType
?这可能会对您有所帮助。