Created
May 6, 2019 14:50
-
-
Save uliwitness/d17abaf383538ec40a5f0936ee6d5836 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
writertest.swift:18:8: error: cannot invoke 'write' with an argument list of type '(T)' | |
impl.write(foo) | |
^ | |
writertest.swift:18:8: note: expected an argument list of type '(T.WriterImplType.ValueType)' | |
impl.write(foo) | |
^ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Abstract base class for values that can be written: | |
protocol Value { | |
associatedtype WriterImplType: WriterImpl | |
} | |
// One concrete kind of value (e.g. a string): | |
class MyValue: Value { | |
typealias WriterImplType = MyWriterImpl | |
} | |
// Generic class for writing values of a certain type: | |
class Writer<T: Value> { | |
typealias WriterImplType = T.WriterImplType | |
let impl: WriterImplType = WriterImplType() | |
func write(_ foo: T) { | |
impl.write(foo) | |
} | |
} | |
// Abstract base class that actually does the writing of a given type for Writer: | |
protocol WriterImpl { | |
associatedtype ValueType: Value | |
init() | |
func write(_ foo: ValueType) | |
} | |
// Concrete writer subclass that Writer can call upon to write MyValue-type values: | |
class MyWriterImpl: WriterImpl { | |
typealias ValueType = MyValue | |
required init() {} | |
func write(_ foo: ValueType) { | |
} | |
} | |
// Create a value and tell the writer to write it: | |
let value = MyValue() | |
let writer = Writer<MyValue>() | |
writer.write(value) |
Hmm… changing to class Writer<T: Value> where T == T.WriterImplType.ValueType {
makes this simplified example compile, but in my actual code, it then complains everywhere Writer is used that 'Writer' requires the types 'T' and 'T.WriterImplType.ValueType' be equivalent
... it doesn't tell me how they are not equivalent, though :/
Does this work for you? It seems like it may avoid the error you're getting throughout your codebase from appearing.
protocol WritableValue{
associatedtype WriterImplType:WriterImpl
}
protocol WriterImpl{
func write<T:WritableValue>(_ value: T) where T.WriterImplType == Self
init()
}
class MyValue: WritableValue{
typealias WriterImplType = MyWriterImpl
}
// Generic class for writing values of a certain type:
class GenericWriter<T: WritableValue> {
typealias WriterImplType = T.WriterImplType
let impl: WriterImplType = WriterImplType()
func write<T:WritableValue>(_ value: T) where T.WriterImplType == WriterImplType {
impl.write(value)
}
}
class MyWriterImpl: WriterImpl {
func write< T : WritableValue>(_ value: T) where T.WriterImplType : MyWriterImpl {
print("The Write:\(value)")
}
typealias ValueType = MyValue
required init() {}
}
// Create a value and tell the writer to write it:
let value = MyValue()
let writer = GenericWriter<MyValue>()
writer.write(value)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Shouldn't T and T.MyWriterImpl.ValueType be the same type in this case? Why is Swift unhappy?