我在 Swift 中遇到关联类型的问题,这可能是由于我缺乏经验造成的。请考虑以下代码,导致内联错误消息:
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")
现在我的实际代码要复杂得多,我现在明白编译器当然无法确保
TA
和 TB
属于同一类型。但是我不知道如何解决这个问题。可能需要在某个地方成为where
,但我不知道从哪里开始这些“通用约束”。任何建议将不胜感激。
如果您想确保
A.TA
的关联类型与 B.TB
匹配,则必须稍微更改您的抽象。
在
B
中,您需要声明另一个associatedtype
,它符合A
并将属性a
声明为这个新的关联类型。完成此操作后,您可以向 where
函数添加 methodB
子句,您可以在其中引用 A.TA
并确保它等于 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")