Skip to content

Instantly share code, notes, and snippets.

@uliwitness
Created May 6, 2019 14:50
Show Gist options
  • Save uliwitness/d17abaf383538ec40a5f0936ee6d5836 to your computer and use it in GitHub Desktop.
Save uliwitness/d17abaf383538ec40a5f0936ee6d5836 to your computer and use it in GitHub Desktop.
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)
^
// 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)
@langford
Copy link

langford commented May 6, 2019

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