0

Based on whether the type is explicitly declared or inferred the below code gives different outputs.

  1. Why does it behave this way. Why can't I implement myFloat in my class if I declare the type?
  2. What do I need to do if i want to declare the type explicitly but also override the implementation in the extension so that the call to testClass1.myFloat() returns 2.7?

This with Xcode 8.1, Swift 2.3

import UIKit

protocol TestSource {
  func myFloat() -> Float
}

extension TestSource {
  func myFloat() -> Float {
    return 2.5
  }
}

protocol TestProtocol: TestSource {

}

class DevClass: TestProtocol {

}

class TestClass: DevClass {
  func myFloat() -> Float {
    return 2.7
  }
}



let testClass1: TestProtocol = TestClass()
testClass1.myFloat() // Returns 2.5

let testClass2 = TestClass()
testClass2.myFloat() // Returns 2.7
Kedar
  • 1,298
  • 10
  • 20
  • You've explicitly declared the type as `TestProtocol`, whose `myFloat` returns 2.5. If you explicitly declare the type as `TestClass`, you'll get 2.7. The whole point of declaring as a type other than the class of the constructor is to get behavior belonging to superclasses or protocols of the class. – BallpointBen Dec 12 '16 at 23:17
  • This is a compiler bug, I remember seeing a very similar question here on SO. – Cristik Dec 12 '16 at 23:28

1 Answers1

0

This is not a bug. The short answer is that protocol extensions to not introduce dynamic dispatch. For a more thorough explanation, see this answer. The explanation there is quite thorough and contains an example.

Here is a blog post that dives even more deeply: https://nomothetis.svbtle.com/the-ghost-of-swift-bugs-future

Community
  • 1
  • 1
Kofi Gumbs
  • 328
  • 2
  • 4
  • Thanks for pointing out the answer. Upvoted at both places and marked this question as duplicate. – Kedar Dec 13 '16 at 20:21