问题是我有一些具有符合某些协议的泛型约束的结构或类。当我尝试根据泛型类型T添加特殊实现时,它对类有效,但对结构无效。我不能在我的特定用例中使用类,因为这个类应该符合需要初始值设定项的协议,但是我不能在扩展中指定类初始值设定项。
有办法让它工作吗?还是我应该选择另一条路?下面是一个演示问题的代码片段。
protocol ProtocolA {}
protocol ProtocolB: ProtocolA {}
protocol ProtocolC {
fun act()
}
struct StructA: ProtocolA {}
struct StructB: ProtocolB {}
struct StructC<T: ProtocolA>: ProtocolC {}
extension StructC {
func act() {
print("general")
}
}
extension StructC where T: ProtocolB {
func act() {
print("special")
}
}
class ClassC<T: ProtocolA>: ProtocolC {
}
extension ClassC {
func act() {
print("general")
}
}
extension ClassC where T: ProtocolB {
func act() {
print("special")
}
}
let classCA = ClassC<StructA>()
let classCB = ClassC<StructB>()
//this works
classCA.act() //-> "general"
classCB.act() //-> "special"
let structCA = StructC<StructA>()
let structCB = StructC<StructB>()
//Does not even compile
structCA.act()
structCB.act() // error: "Ambigous use of 'act()'"
UPD:如果我使用protocol with type alias和extend protocol而不是struct,那么它可以工作:
protocol ProtocolD {
typealias V
func act()
}
struct StructD<T: ProtocolA>: ProtocolD {
typealias V = T
}
extension ProtocolD {
func act() {
print("general")
}
}
extension ProtocolD where V: ProtocolB {
func act() {
print("special")
}
}
let structDA = StructD<StructA>()
let structDB = StructD<StructB>()
//works again
structDA.act() //-> "general"
structDB.act() //-> "special"
但它仍然不能解决或解释类和结构的不同行为问题。
UPD:该问题的雷达存档rdar://23314307
最佳答案
从第一眼看到你在这里申报
`let structCB = StructC<StructB>()`
但是,当StructB只继承此协议时,使用ProtocolB实现扩展:
extension StructC where T: ProtocolB {
func act() {
print("special")
}
}
StructB
继承ProtocolB
,但ProtocolB
不“继承”StructB
。如果将此扩展设置为默认实现,则它将工作:
extension StructC where T: StructB {
func act() {
print("special")
}
}
升级版:
最后我明白了你的问题,也变得很感兴趣——为什么它不起作用。
问题是
protocol ProtocolB: ProtocolA {}
然后在泛型中
ProtocolB
不被视为来自ProtocolA
的继承。我想你可以改变一下你的逻辑来解决这个问题:您的
ProtocolB
通过添加一些函数来扩展ProtocolA
。如果可以接受,可以在StructB
中添加函数