Hi Isaac,

This is not about associated types. Rather, the issue is that a ‘Thing’ is a 
‘Something<UINavigationController>’, but you are casting it to 
‘Something<UIViewController>’. The two types are not related; in general, if A 
is a subtype of B, then G<A> is not a subtype of G<B>.

https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)

Slava

> On Feb 16, 2017, at 9:05 AM, Isaac Rivera via swift-users 
> <[email protected]> wrote:
> 
> Hello, list!
> 
> I am trying to find my way around Swift’s protocol limitations. It appears 
> that in general, any protocol with declared associatedtype will break 
> polymorphism?
> 
> Take the case below which does not compile. All "Thing” instances are 
> "Something<VC: UIViewController>” but they can’t be passed around or coerced 
> as so.
> 
> How is it that I can legally write the code:
> 
> class Thing: Something<UINavigationController> { }
> 
> and instantiate it, but it is not the very thing it implements? 
> 
> All Thing instances conform to the public interfaces of 
> Something<UIViewController> so why can’t they be recognized as such and 
> coerced as such?
> 
> What is the work-around of this break in Polymorphism?
> 
> import UIKit
> 
> protocol Anything: class, NSObjectProtocol {
>       
>       associatedtype ViewControllerType: UIViewController
>       
>       var viewController: ViewControllerType { get }
>       
>       init(viewController: ViewControllerType)
>       
>       func addAnything(anything: Something<UIViewController>) -> Bool
> }
> 
> class Something<VC: UIViewController>: NSObject, Anything {
>       
>       typealias ViewControllerType = VC
>       
>       private(set) var viewController: ViewControllerType
>       
>       required init(viewController: ViewControllerType) { self.viewController 
> = viewController }
>       
>       final private var things = [String: Something<UIViewController>]()
>       
>       final internal func addAnything(anything: Something<UIViewController>) 
> -> Bool {
>               // implementation details...
>               return true
>       }
> }
> 
> class Thing: Something<UINavigationController> { }
> 
> let firstThing = Thing(viewController: UINavigationController())
> let secondThing = Thing(viewController: UINavigationController())
> 
> firstThing.addAnything(anything: secondThing)
> 
> // Playground execution failed: error: MyPlayground.playground:48:34: error: 
> cannot convert value of type 'Thing' to expected argument type 
> 'Something<UIViewController>'
> 
> firstThing.addAnything(anything: secondThing as Something<UIViewController>)
> 
> // Playground execution failed: error: MyPlayground.playground:48:34: error: 
> cannot convert value of type 'Thing' to type 'Something<UIViewController>' in 
> coercion
> 
> 
> 
> 
> _______________________________________________
> swift-users mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-users

Reply via email to