An online Swift 5.1 compiler compiles the following code and reports errors. The most important one is stated as follows:
main.swift:18:23: error: reference to invalid associated type 'Other' of type 'Sparrow'
func sing(with f: Other) {
^
Another thread on Stackoverflow brought up the same issue with a more complicated case. (Reference to invalid associated type 'Iterator' of type 'DecodedArray<T>'). There have been no answers to that thread yet.
The code for my case and a full list of compiler-reported errors is shown below:
protocol Flier {
associatedtype Other
func flockTogether(with f:Other)
func sing(with f:Other)
}
struct Sparrow : Flier {
let name: String
init (_ name: String) {
self.name = name
}
func flockTogether(with f: Other) {
print("Birds, \(name), and \(f.name), of a feather flock together.")
}
func sing(with f: Other) {
sing()
f.sing()
}
func sing () {
print("Sparrow sings \"chirp, chirp\"!")
}
}
struct Parrot {
let name: String
init (_ name: String) {
self.name = name
}
func sing () {
print("Parrot sings \"chuck, chuck\"!")
}
}
struct Canary: Flier {
let name: String
init (_ name: String) {
self.name = name
}
func flockTogether(with f: Other) {}
func sing(with f: Other) {}
func sing () {
print("Canary sings \"tweet, tweet\"!")
}
}
let sparrow = Sparrow("sparrow")
let parrot = Parrot("parrot")
let canary = Canary("canary")
sparrow.flockTogether(with: parrot)
sparrow.sing(with: parrot)
sparrow.flockTogether(with: canary)
sparrow.sing(with: canary)
The errors reported by the compiler:
main.swift:18:23: error: reference to invalid associated type 'Other' of type 'Sparrow'
func sing(with f: Other) {
^
main.swift:8:8: error: type 'Sparrow' does not conform to protocol 'Flier'
struct Sparrow : Flier {
^
main.swift:2:20: note: protocol requires nested type 'Other'; do you want to add it?
associatedtype Other
^
main.swift:38:8: error: type 'Canary' does not conform to protocol 'Flier'
struct Canary: Flier {
^
main.swift:2:20: note: protocol requires nested type 'Other'; do you want to add it?
associatedtype Other
^
compiler exit status 1
Please help me find out what has gone wrong in the above code. Thank you very much!
There are quite a few things wrong with this code.
SparrowandCanaryare declared to conform toFlieryet doesn't say what their respectiveOthertype is.You are trying to pass both a
parrotand acanarytosparrow.flockTogether(with:)andsparrow.sing(with:), but those methods only accept one type of object -Sparrow.Other. This, and the above point, suggest that you might be misunderstanding what associated types are. I suggest you read about them.You are trying to access things that doesn't necessarily exist, such as
f.nameandf.sing(). Recall thatfis anOther, which is not constrained to any type, so it can be anything. And "anything" won't always have anamefor you to access.I suggest the following to make the callers work:
Remove the associated type and use generic methods instead. Associated types are inappropriate if the caller gets to decide whether to pass in a
ParrotorCanary.Add
nameandsing()toFlierso that the compiler knows that anything conforming toFlierhas those members. If we then constrainOther(the generic parameter of the aforementioned generic methods) toFlier, then we can accesssing()andnamewithout any problems.Conform
ParrottoFlieras wellThe fixed code now looks like: