我有以下类:
class MyClass<T: BaseClass> {
let aThing = T()
func someMethod() {
configure()
}
}
而
class SubTypeAOfBaseClass: BaseClass { ... }
class SubTypeBOfBaseClass: BaseClass { ... }
在configure
中,我想根据其类型配置aThing
。因此,我创建了一个协议Configurable
和一个扩展:
protocol Configurable {
func configure()
}
extension MyClass: Configurable where T == SubTypeAOfBaseClass {
func configure() {
print("Configuring SubTypeAOfBaseClass")
aThing.doSomethingA()
}
}
我得到的错误是在CCD_ 4中,在那里我调用CCD_;引用实例方法configure((需要类型T和SubTypeAOfBaseClass等效。
当我添加以下扩展时的另一个错误:
extension MyClass: Configurable where T == SubTypeBOfBaseClass {
func configure() {
print("Configuring SubTypeBOfBaseClass")
aThing.doSomethingB()
}
}
错误变为"0";在调用实例方法configure"时没有完全匹配;和在线
extension MyClass: Configurable where T == SubTypeBOfBaseClass {
我得到错误";MyClass与可配置协议的一致性存在冲突,即使条件边界不同,也不能有多个一致性">
它应该工作,但显然我错过了一些东西,或者我对如何实现我想要的东西的理解是错误的。
考虑当T
是BaseClass
时,或者当T
是我定义为的AnotherSubclass
时的情况
class AnotherSubclass : BaseClass {
}
会发生什么?当T
是AnotherSubclass
时,您还没有声明对Configure
的一致性!
这里真的只有两个(不错的(选择。
- 当
T
既不是SubTypeAOfBaseClass
也不是SubTypeBOfBaseClass
时,您希望configure
不执行任何操作 - 您只希望
MyClass<SubTypeAOfBaseClass>
和MyClass<SubTypeBOfBaseClass>
是有效类型——MyClass<BaseClass>
和MyClass<AnotherSubclass>
会导致编译器错误
选择2在Swift中不可用。这将需要类似于Java或Kotlin中的密封类型的东西。
选择1可以这样做:
class BaseClass {
...
func configure() {
}
}
class SubTypeAOfBaseClass: BaseClass {
...
override func configure() {
print("Configuring SubTypeAOfBaseClass")
doSomethingA()
}
}
class SubTypeBOfBaseClass: BaseClass {
...
override func configure() {
print("Configuring SubTypeAOfBaseClass")
doSomethingB()
}
}
class MyClass<T: BaseClass> {
let aThing = T()
func someMethod() {
aThing.configure()
}
}
您可能会注意到,configure
的每个实现都已移动到基类中。如果你想在MyClass
中实现它们,你必须手动检查类型:
class MyClass<T: BaseClass> {
let aThing = T()
func someMethod() {
if let selfA = self as? MyClass<SubTypeAOfBaseClass> {
selfA.configure()
} else if let selfB = self as? MyClass<SubTypeBOfBaseClass> {
selfB.configure()
}
}
}
extension MyClass where T == SubTypeAOfBaseClass {
func configure() {
print("Configuring SubTypeAOfBaseClass")
aThing.doSomethingA()
}
}
extension MyClass where T == SubTypeBOfBaseClass {
func configure() {
print("Configuring SubTypeBOfBaseClass")
aThing.doSomethingB()
}
}
这是因为代码中的第二个问题——泛型类型MyClass<SubTypeAOfBaseClass>
和MyClass<SubTypeBOfBaseClass>
的不同参数不能以不同的方式符合协议。不幸的是,这是Swift的局限性。请参阅此处了解更多信息。