Swift协议和扩展,如果它存在,我需要调用实例方法

问题描述 投票:0回答:2

我有一个协议Foo及其扩展如下:

protocol Foo {
    func test()    
}

extension Foo {
    func test() {
        print("foo")
    }
}

我也有像这样的协议类:

class Bar: Foo {
    func test() {
        print("bar")
    }
}

和测试人员如下:

func tester<T: Foo>(_ obj: T) {
   obj.test()
}

let myBar = Bar()
tester(myBar)

在输出中我有:

FOO

但预计 - 吧

我如何从我的test()调用实例方法tester

swift swift-protocols
2个回答
1
投票

这完全取决于两件事:

  • 这是协议的要求还是仅通过扩展注入?
  • 接收器是键入Foo还是Bar?

例如:

protocol Foo {
    // func test() // note we've commented this out!
}
extension Foo {
    func test() {
        print("foo")
    }
}
class Bar: Foo {
    func test() {
        print("bar")
    }
}
let myBar = Bar()
myBar.test() // bar
let myFoo : Foo = Bar()
myFoo.test() // foo

但如果你取消注释我注释掉的那一行,现在你总是打印出"bar"


0
投票

如果在协议中声明函数,则使用见证表动态调度它,即如果从派生实现调用它,则将获得被覆盖的版本。如果在扩展中声明函数(并且未在协议中声明),则会静态调度该函数,并根据您调用它的类型(即没有多态性)获取版本。这样做的原因是编译器必须在编译时知道协议函数和变量声明以生成见证表,并且在编译时它无法知道所有可能的扩展。

© www.soinside.com 2019 - 2024. All rights reserved.