具有关联类型和阴影类型擦除的Swift协议

具有关联类型和阴影类型擦除的Swift协议,swift,protocols,swift-protocols,associated-types,Swift,Protocols,Swift Protocols,Associated Types,我需要将一个实现具有关联类型的协议的对象传递给一个接受协议的方法。这在Swift中是不可能的(直到最新的Swift 5),所以我使用类型擦除和基于的阴影协议 问题是,当我将对象传递到方法中时,会调用“shadow的默认实现”,而不是“generic”实现。您可以检查以查看正在发生的情况 Swift中是否存在错误或此用例根本不可能使用?此动态调度和直接调度魔术了解有关此检查的更多解释 动态调度是选择一个应用程序的哪个实现的过程 要在运行时调用的多态操作(方法或函数) 在协议扩展中实现的任何方法都是

我需要将一个实现具有关联类型的协议的对象传递给一个接受协议的方法。这在Swift中是不可能的(直到最新的Swift 5),所以我使用类型擦除和基于的阴影协议

问题是,当我将对象传递到方法中时,会调用“shadow的默认实现”,而不是“generic”实现。您可以检查以查看正在发生的情况


Swift中是否存在错误或此用例根本不可能使用?

此动态调度和直接调度魔术了解有关此检查的更多解释

动态调度是选择一个应用程序的哪个实现的过程 要在运行时调用的多态操作(方法或函数)

协议扩展
中实现的任何方法都是直接调度的

我会详细解释

因为
ShadowA
protocol
并且在扩展中有
默认实现
,所以编译器有这个提示“
任何类都可以采用这个协议而不实现这个方法,因为它有默认实现

直接调度

所以在这一行,编译器从item中知道了什么关于
test(data:Any)
,因为item是带有默认实现的协议,所以它指示它调用直接默认实现

return "in method: \(item.test(data: 0))"

func passedIntoMethod(item: ShadowA) -> String {
    return "in method: \(item.test(data: 0))"
}
let a1 = SpecificA()
print(a1.test(data: 0))
也在这条线上

let a2: ShadowA = SpecificA()   // becuse compiler know only about a2 at this line that it is Protocol so it direct dispatch it  
print(a2.test(data: 0))
动态调度

在这里,编译器知道a1是concreate类型,所以它调用在其内部实现的测试方法。如果没有实现,那么它将调用默认实现

return "in method: \(item.test(data: 0))"

func passedIntoMethod(item: ShadowA) -> String {
    return "in method: \(item.test(data: 0))"
}
let a1 = SpecificA()
print(a1.test(data: 0))

有趣的是,当我在一个接受影子协议的方法中有一个断点时,程序会暂停,然后当我从调试器调用该方法时,会在对象上调用正确的“泛型”方法。然后跳过代码,该代码调用与我从调试器调用的方法相同的方法,调用“shadow方法”,即调试器调用泛型方法,而实际代码调用shadow方法。分派是在运行时进行的,调试器将方法中的对象视为具体类型(而不仅仅是shadow协议)因此它可以/将调用正确的方法?