如何使用通用约束来关联不同协议中的两个关联类型

问题描述 投票:0回答:1

我在 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
,但我不知道从哪里开始这些“通用约束”。任何建议将不胜感激。

swift swift-protocols
1个回答
0
投票

如果您想确保

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")
© www.soinside.com 2019 - 2024. All rights reserved.