2

Sample code which I am experimenting in playground

protocol Shape {
    init()
}

class Circle: Shape {
    required init() {
    }
}

class Square: Shape {
    required init() {
    }
}

class ShapeMapping<T> {
    func map() -> T? {
        print("Any shape called")
        return nil
    }
}

extension ShapeMapping where T: Shape {
    func map() -> T? {
        print("Shape type called")
        return T.self()
    }
}

extension ShapeMapping where T: Square {
    func map() -> T? {
        print("Square type called")
        return Square() as? T
    }
}

class ShapeWrapper<T> {
    func determineShape() -> T?  {
        return ShapeMapping<T>().map()
    }

}

Code works correctly and calls expected method for type Square when I call

let square: Square? = ShapeMapping<Square>().map()

Output: Square type called

But, when I call a wrapper method and pass Square type output is different

let mappingSquareShape: Square? = ShapeWrapper<Square>().determineShape()

Actual: Any shape called
Expected: Square type called

Is type information does not get passed from ShapeWrapper to ShapeMapping? Any idea what's going on here?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Gopal
  • 1,719
  • 12
  • 13
  • 1
    extensions can't define overrides like this. – Alexander May 27 '17 at 01:36
  • As per apple docs nothing wrong when explicitly specifying type with extension https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Generics.html#//apple_ref/doc/uid/TP40014097-CH26-ID553 – Gopal May 27 '17 at 01:56
  • 1
    No there's nothing wrong with it, it just won't have the polymorphic behaviour youre looking for – Alexander May 27 '17 at 02:30
  • 1
    Compare [Wrong specialized generic function gets called in Swift 3 from an indirect call](https://stackoverflow.com/q/41980001/2976878). Inside `determineShape()`, the compiler doesn't know anything about the type of `T` – it could be an arbitrary type. Therefore the only overload of `map()` it can dispatch to is the unconstrained one on `ShapeMapping`. – Hamish May 27 '17 at 09:13

1 Answers1

0

In your code I found "func map()" will be ambiguous when i define the class ShapeMapping(), The compiler will not know which one to use, maybe you can change the method name in the extension

extension ShapeMapping where T: Shape{
  func test() -> T? {
    print("Shape type called")
    return nil
  }
}
yy_xuelangwang
  • 171
  • 1
  • 5