Dynamic/runtime dispatch in Swift, or “the strange way structs behave in one man's opinion”

做~自己de王妃 提交于 2019-11-28 12:33:49
Hamish

In your first example you're overriding the description property. This implementation is therefore added to OddString's vtable (as it's a class), and can be dynamically dispatched to just fine, regardless of what the instance is statically typed as.

In your second example, you don't have a class – so no vtables. However you are conforming to a protocol. Protocols allow for dynamic dispatch via protocol witness tables (see this great WWDC talk on them), however this only happens for implementations of protocol requirements.

localizedDescription isn't a protocol requirement of the Error protocol, it's merely defined in a protocol extension of Error when you import Foundation (this is documented in SE-0112). Therefore it cannot be dynamically dispatched. Instead, it will be statically dispatched – so the implementation called is dependant on the static type of the instance.

That's the behaviour you're seeing here – when your explosive instance is typed as TestError, your implementation of localizedDescription is called. When typed as Error, the implementation in the Error extension is called (which just does a bridge to NSError and gets its localizedDescription).

If you want to provide a localised description, then you should conform your error type to LocalizedError instead, which defines errorDescription as a protocol requirement – thus allowing for dynamically dispatch. See this Q&A for an example of how to go about this.

localizedDescription is both an extension on the Error protocol and a property on your error type. When the compiler knows that your type implements the property, it uses it. When it doesn't, it uses the extension. There is no dynamic dispatch.

Contrast with your String example, where, by overriding the description member, the compiler puts a reference to your implementation in the vtable, and as such it will be dynamically dispatched.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!