Franklin Yu Franklin Yu - 5 months ago 11
Swift Question

protocol with same associated type name

If I have two protocols whose associated type happens to be the same, such as

protocol Read {
associatedtype Element
func read() -> Element
}
protocol Write {
associatedtype Element
func write(a: Element)
}


Then I would like to have a class to read integer from and write string to:

class ReadWrite: Read, Write {
func read() -> Int {
return 5
}
func write(a: String) {
print("writing \(a)")
}
}


but the compiler complains and suggests changing
String
to
Int
. Ideally the type should be inferred, or at least compiles if I explicitly declare

associatedtype Read.Element = Int
associatedtype Write.Element = String


within
ReadWrite
. Any work around?

update



Workaround inspired by this question is to create two auxiliary protocols

protocol ReadInt: Read {
associatedtype Element = Int
}
protocol WriteString: Write {
associatedtype Element = String
}


and have the class inherit from these two instead:

class ReadWrite: ReadInt, WriteString {
func read() -> Int {
return 5
}
func write(a: String) {
print("writing \(a)")
}
}


This seems to compile, but I am afraid of any gotcha following this way.

update again



I found the issue in Swift's issue tracker. Anyone require this missing feature (like me) should vote for it.

Answer

Another workaround is to create a third, combined protocol:

protocol ReadWrite {
    associatedtype R
    associatedtype W
    func read() -> R
    func write(a: W)
}

It's not pretty, since it forces you to redeclare the protocol members, but it does keep it generic (you're not limited to String and Int).

Comments