繁体   English   中英

带有关联类型和影子类型擦除的Swift协议

[英]Swift protocol with associated type and shadow type erasure

我需要将实现具有关联类型的协议的对象传递给接受协议的方法。 这在Swift(最新的Swift 5)中是不可能的,因此我在此Blog的影子协议中使用了类型擦除。

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"
    }
}

问题是,当我将对象传递给方法时,将调用“阴影的默认实现”,而不是“通用”实现。 您可以检查操场上看到的情况。

是否有问题或在Swift中根本无法使用该用例?

此动态分派和直接分派Magic进一步说明了有关检查此swift-method-dispatch的信息

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

protocol extension中实现的任何方法都是直接分派的

我会解释更多

因为ShadowAprotocol并且在扩展中具有default implementation ,所以编译器会想到以下提示:“ Any class can adopt to this protocol without implement this method because it have default implementation

直接派遣

所以在这一行,编译器从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 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类型,因此它调用在其内部实现的test Method。 如果没有实现,它将调用默认实现

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM