gpt4 book ai didi

具有关联类型和影子类型删除的 Swift 协议(protocol)

转载 作者:行者123 更新时间:2023-11-28 07:29:16 36 4
gpt4 key购买 nike

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

protocol ShadowA {
func test(data: Any) -> String
}

extension ShadowA {
func test(data: Any) -> String {
return "shadow"
}
}

protocol A: ShadowA {
associatedtype AT

func test(data: AT) -> String
}

class SpecificA: A {
typealias AT = Int

func test(data: Int) -> String {
return "specific"
}
}

问题是,当我将对象传递给方法时,会调用“影子的默认实现”而不是“通用”实现。您可以查看 playground看看发生了什么。

有什么问题吗?或者这个用例在 Swift 中根本不可能吗?

最佳答案

这个动态调度和直接调度魔术的更多解释检查这个swift-method-dispatch

Dynamic dispatch is the process of selecting which implementation of a polymorphic operation (method or function) to call at run time.

protocol extension 中实现的任何方法都是Direct dispatched

我会解释更多

因为 ShadowAprotocol 并且在扩展中有 default implementation 所以编译器头脑有这个提示 "Any class can adopt to this没有实现此方法的协议(protocol),因为它具有默认实现"

直接派送

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

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

func passedIntoMethod(item: ShadowA) -> String {
return "in method: \(item.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 类型,所以它调用在它内部实现的测试方法。如果没有实现,那么它将调用默认实现

let a1 = SpecificA()
print(a1.test(data: 0))

关于具有关联类型和影子类型删除的 Swift 协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55449954/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com