I can see it is a (counter-intuitive) language design decision for type safety… but then why, in the code below I can:
class OtherThing: Something<UIViewController> { override func start(_ completion: SomeCallback? = nil) { // implementation details... } } let firstThing = OtherThing(viewController: UINavigationController()) OtherThing extends Something<UIViewController>… but I can instantiate it with the subtype… Ok you will say, UINavigationController is a subtype of UIViewController, but that still does not make Something<UINavigationController> a subtype of Something<UIViewController>. Fair enough, but: let c1: Something<UIViewController> = Something(viewController: UINavigationController()) // c1 is of type "Something<UIViewController>" let c2 = Something(viewController: UINavigationController()) // c1 is of type "Something<UINavigationController>” So it appears Something<UINavigationController> can be cast to type Something<UIViewController>… Yet this is illegal? let somethings: [Something<UIViewController>] = [c1, c2] I dont know, something seems inconsistent. > On Feb 16, 2017, at 10:59 PM, Slava Pestov <spes...@apple.com> wrote: > > 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 >> <swift-users@swift.org> 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 >> swift-users@swift.org >> https://lists.swift.org/mailman/listinfo/swift-users >
_______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users