在运行时,Swift 如何知道要使用哪个实现?

At runtime, how does Swift know which implementation to use?

protocol A {
    func f()
}

struct S1 : A {
    func f() {
        print("S1")
    }
}

struct S2 : A {
    func f() {
        print("S2")
    }
}

let array: [A] = [S1(), S2()]

for s: A in array {
    s.f()
}

// "S1\n" "S2\n"

如果这是一个继承层次结构,我希望 Swift 使用 v-table 来查找正确的实现。然而,array 中的具体类型可以是任何实现 A 的东西,以及任意数量的其他协议,所以 Swift 运行时如何知道对象的结构,如果它也是使用 v-tables?

Swift 运行时使用 Protocol Witness Table,它包含指向每个类型的协议方法实现的指针。

Mike Ash 在他的文章 Exploring Swift Memory Layout, Part II:

中对其进行了最好的解释

The last one, at offset 32 is a "protocol witness table" for the underlying type and the protocol, which contains pointers to the type's implementations of the protocol methods. This is how the compiler is able to invoke methods, such as p(), on a value of protocol type without knowing the underlying type at runtime.

我也会按照 Hamish 评论中的建议观看 WWDC 视频 Understanding Swift Performance