我正在尝试使用两个相互关联的通用协议:
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未能编译说Type 'Test' does not conform to protocol 'PersistentDataModel'
并暗示Possibly intended match 'DataStoreType' (aka 'StringDataStore') does not conform to 'DataStore'
而StringDataStore
被定义为符合DataStore
我已经阅读了一些有关通用协议的很好的资源,包括SO和这个Medium post,但是我找不到问题所在。
答案 0 :(得分:2)
之所以会这样,是因为您的typealias
的{{1}}应该是具体的,而不是抽象的。
因此,对于您的情况,associatedtype
应该是StringDataStore
,而不是class
。
protocol
但是,您可以继续使用协议并通过在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
}
类中使用其他泛型条件来解决它:
Test
使用此方法,您可以告诉编译器具体类型将被传递到其他地方的class Test<T: StringDataStore>: PersistentDataModel where T.DataType == String {
typealias DataStoreType = T
typealias DataType = T.DataType
}
。
赞:
Test