I've a problem with associated types in Swift, that probably result from my lack of experience. Please consider the following Code, resulting in the inlined error message:
protocol A {
associatedtype TA
}
protocol B {
associatedtype TB
var a: any A { get }
}
extension A {
func methodA(param: TA) {
print(param)
}
}
extension B {
func methodB(param: TB) {
a.methodA(param: param) // Member 'methodA' cannot be used on value of type 'any A'; consider using a generic constraint instead
}
}
class AImpl: A {
typealias TA = String
}
class BImpl: B {
typealias TB = String
var a: any A = AImpl()
}
let b = BImpl()
b.methodB(param: "Hello World")
Now my actual code was much more complex and I do understand now that the compiler of course is unable to ensure TA
and TB
are of the same type. I however have no idea how to solve this. The probably needs to be a where
somewhere, but I got no idea where to even start with these 'generic constraints'. Any suggestions would be much appreciated.
You have to change your abstraction a bit if you want to ensure that the associated type of A.TA
matches B.TB
.
In B
, you need to declare another associatedtype
, which conforms to A
and declare the property a
to be of this new associated type. Once you do this, you can add a where
clause to the methodB
function where you can refer to A.TA
and make sure that it equals TB
.
protocol A {
associatedtype TA
}
protocol B {
associatedtype SpecificA: A
associatedtype TB
var a: SpecificA { get }
}
extension A {
func methodA(param: TA) {
print(param)
}
}
extension B {
func methodB(param: TB) where SpecificA.TA == TB {
a.methodA(param: param)
}
}
class AImpl: A {
typealias TA = String
}
class BImpl: B {
typealias TB = String
var a = AImpl()
}
let b = BImpl()
b.methodB(param: "Hello World")