Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift:具有协议和子类的动态调度 请考虑以下SWIFT 5代码: protocol P: class { func call_foo() func foo() func call_bar() func bar() } extension P { func call_foo() { foo() } func foo() { print("P.foo") } func call_bar() { bar() } func bar() { print("P.bar") } } class C1: P { func foo() { print("C1.foo") } } class C2: C1 { func bar() { print("C2.bar") } } let c = C2() c.call_foo() // C1.foo c.foo() // C1.foo c.call_bar() // P.bar c.bar() // C2.bar_Swift_Protocols_Dynamic Dispatch - Fatal编程技术网

Swift:具有协议和子类的动态调度 请考虑以下SWIFT 5代码: protocol P: class { func call_foo() func foo() func call_bar() func bar() } extension P { func call_foo() { foo() } func foo() { print("P.foo") } func call_bar() { bar() } func bar() { print("P.bar") } } class C1: P { func foo() { print("C1.foo") } } class C2: C1 { func bar() { print("C2.bar") } } let c = C2() c.call_foo() // C1.foo c.foo() // C1.foo c.call_bar() // P.bar c.bar() // C2.bar

Swift:具有协议和子类的动态调度 请考虑以下SWIFT 5代码: protocol P: class { func call_foo() func foo() func call_bar() func bar() } extension P { func call_foo() { foo() } func foo() { print("P.foo") } func call_bar() { bar() } func bar() { print("P.bar") } } class C1: P { func foo() { print("C1.foo") } } class C2: C1 { func bar() { print("C2.bar") } } let c = C2() c.call_foo() // C1.foo c.foo() // C1.foo c.call_bar() // P.bar c.bar() // C2.bar,swift,protocols,dynamic-dispatch,Swift,Protocols,Dynamic Dispatch,如果foo()调用p.call\u foo()被动态调度到C1.foo(),那么为什么bar()调用p.call\u bar()没有被动态调度到C2.bar() 唯一的区别是foo()在符合p的类中被直接重写,bar()仅在子类中被重写。为什么会有不同 鉴于bar()是协议要求,对它的所有调用不应该总是动态调度吗?在您的扩展上下文中: extension P { func call_foo() { foo() } func foo() { print("P.foo&qu

如果
foo()
调用
p.call\u foo()
被动态调度到
C1.foo()
,那么为什么
bar()
调用
p.call\u bar()
没有被动态调度到
C2.bar()

唯一的区别是
foo()
在符合
p
的类中被直接重写,
bar()
仅在子类中被重写。为什么会有不同


鉴于
bar()
是协议要求,对它的所有调用不应该总是动态调度吗?

在您的扩展上下文中:

extension P {
    func call_foo() { foo() }
    func foo() { print("P.foo") }
    func call_bar() { bar() }
    func bar() { print("P.bar") }
}
C2
不存在,
p
是一个协议,方法是静态调度的,虽然
bar()
p
的一个要求,但它不是由符合
p
C1
实现的,因此:

let c1: some P = C1()
c1.call_foo()    //  C1.foo
c1.foo()         //  C1.foo
c1.call_bar()    //  P.bar
c1.bar()         //  P.bar
这很正常,有趣的是你有:

let someP: some P = C2()
someP.call_foo()    //  C1.foo
someP.foo()         //  C1.foo
someP.call_bar()    //  P.bar
someP.bar()         //  P.bar
这意味着,如果您只引用了
某些p
,则
C1
的子类
C2
的行为与它的超类完全相同:
call\u bar()
调用
p.bar()
,因为
C1
没有实现
bar()

现在让我们看看如果在
C1
中实现
bar()
会发生什么:

class C1: P {
    func foo() { print("C1.foo") }
    func bar() { print("C1.bar") }
}

class C2: C1 {
    override func bar() { print("C2.bar") }
}
如果我们使用
some p
引用
C1

let c1: some P = C1()
c1.call_foo()    //  C1.foo
c1.foo()         //  C1.foo
c1.call_bar()    //  C1.bar
c1.bar()         //  C1.bar
let someP: some P = C2()
someP.call_foo()    //  C1.foo
someP.foo()         //  C1.foo
someP.call_bar()    //  C2.bar
someP.bar()         //  C2.bar
现在在
call\u bar()
中,编译器知道它必须使用
C1.bar()
,因此对于
C2
的引用,使用
一些p

let c1: some P = C1()
c1.call_foo()    //  C1.foo
c1.foo()         //  C1.foo
c1.call_bar()    //  C1.bar
c1.bar()         //  C1.bar
let someP: some P = C2()
someP.call_foo()    //  C1.foo
someP.foo()         //  C1.foo
someP.call_bar()    //  C2.bar
someP.bar()         //  C2.bar
子类
C2
的行为仍然与它的超类
C1
相同,并且它的
bar()
get的实现被调用。(当子类的行为与它们的父类相同时,我会发现这一点)

现在让我们检查原始代码段:

let c = C2()
c.call_foo()    //  C1.foo
c.foo()         //  C1.foo
c.call_bar()    //  C2.bar
c.bar()         //  C2.bar

它的工作

我是否正确理解,
C1
与p的一致性只有一个见证表(与之相反,
C1
的每个子类都有一个单独的见证表),在
C1
的所有实例或其任何子类之间共享?是的,有关更多详细信息,请参见@Hamish answer here:好的,谢谢。这解释了我所看到的行为,尽管我仍然不理解背后的原理。谢谢你的链接,我会继续阅读。