Следующий код работает так, как и ожидалось:
protocol Storeable {
associatedtype Value
func create(value: Value)
}
struct DefaultStore<V>: Storeable {
typealias Value = V
func create(value: V) {
print("base impl. is called with value type: \(String(describing: V.self))")
}
}
class Event {
var title: String = ""
init(title: String) {
self.title = title
}
}
extension DefaultStore where Value: Event {
func create(value: V) {
print("event impl. is called with event: \(value.title)")
}
}
DefaultStore().create(value: Event(title: "Dance Party"))
// prints "event impl. is called with event: Dance Party"
DefaultStore().create(value: "a string object")
// prints "base impl. is called with value of type: String"
В основном я вызываю функцию в обобщенном c классе DefaultStore
, и компилятор вызывает правильную реализацию в зависимости от базового типа.
Теперь у меня есть сценарий, в котором я хочу точно такую же вещь, за исключением того, что она обернута в другой объект с именем Wrapper
:
struct Wrapper<StoreType: Storeable,ValueType> where StoreType.Value == ValueType {
let store: StoreType
func create(value: ValueType) {
store.create(value: value)
}
}
let defaultStore = DefaultStore<Event>()
let wrapper = Wrapper(store: defaultStore)
wrapper.create(value: Event(title: "Düsseldorfer Symphoniker"))
// prints: "base impl. is called with value of type: Event"
Здесь я ожидаю, что расширение для Event
вызывается, но вместо этого вызывается базовая реализация. Кто-нибудь знает, что я делаю не так?
-
Обновление:
@ matt предполагал, что может быть проблема времени компиляции: "без оболочки, когда вы говорите DefaultStore().create...
Событие Информация может быть прочитана вплоть до параметризованного типа DefaultStore generi c. Но в вашей оболочке сначала создается DefaultStore, поэтому он является общим типом и все. "
I Полагайте, что это не так, потому что вы также можете сначала создать DefaultsStore
, и он все еще работает без Обертки. Также компилятор предупреждает меня, если типы не совпадают.