<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Nov 3, 2016, at 11:07, has <<a href="mailto:hengist.podd@nuggle.uk" class="">hengist.podd@nuggle.uk</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">Robert Nikander wrote:<br class=""><blockquote type="cite" class="">Cc:"<a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a>" <<a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a>><br class="">Subject: Re: [swift-users] wishing I could cast (sort of) to protocol<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>with associated type<br class="">Message-ID:<<a href="mailto:BF76DEE9-ACA5-4A74-A4F0-FEBB84A422A4@apple.com" class="">BF76DEE9-ACA5-4A74-A4F0-FEBB84A422A4@apple.com</a>><br class="">Content-Type: text/plain; charset="utf-8"<br class=""><br class="">The only real way to do this today is to have two layers of protocol:<br class=""><br class="">protocol SpecialControllerBase {<br class=""> var currentValueBase: SpecialValue? { get }<br class="">}<br class="">protocol SpecialController: SpecialControllerBase {<br class=""> associatedtype SpecialValueType : SpecialValue<br class=""> var currentValue: SpecialValueType? { get }<br class="">}<br class="">extension SpecialController {<br class=""> var currentValueBase: SpecialValue? { return self.currentValue }<br class="">}<br class=""></blockquote><br class="">One other option may be to put a typealias in an extension instead of declaring an associated type:<br class=""><br class="">// The almost-a-generic protocol:<br class=""><br class="">protocol AssProtocol {<br class=""> var xxx: AssType { get }<br class="">}<br class=""><br class="">extension AssProtocol {<br class=""> typealias AssType = Any<br class="">}<br class=""><br class="">// My concrete classes:<br class=""><br class="">class MyClass1: AssProtocol {<br class=""> typealias AssType = Int<br class=""> var xxx: AssProtocol.AssType { return 1 }<br class="">}<br class=""><br class="">class MyClass2: AssProtocol {<br class=""> typealias AssType = String<br class=""> var xxx: AssProtocol.AssType { return "two" }<br class="">}<br class=""><br class="">// A generic function that uses the aforementioned protocol:<br class=""><br class="">func doit<T>(_ v: T) where T: AssProtocol.AssType {<br class=""> print(v, type(of: v))<br class="">}<br class=""><br class="">// The rare sweet joy that is 0 compiler errors AND 0 runtime crashes:<br class=""><br class="">let res1 = MyClass1().xxx<br class="">let res2 = MyClass2().xxx<br class=""><br class="">doit(res1) // 1 Int.Type<br class="">doit(res2) // two String.Type<br class=""><br class=""><br class="">Needless to say my head is screeching "probable undefined behavior" even as I type this, so caveat emptor, E&OE, don't blame me when it eats your cat and marries your wife, etc. [1] But it did finally get me out of an unspeakably intractable problem with the Swift type system, thus preserving what precious few last shreds of sanity I still possess. Who knows, now that I only have a myriad of all-but-intractable problems left to work through, one day I might even release!</div></div></blockquote><br class=""></div><div>To see what this is actually doing, try this instead:</div><div><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div>func doit<T>(_ v: T) where T: AssProtocol.AssType {</div><div> print(T.self)</div><div>}</div></blockquote><div class=""><br class=""></div><div class="">(and compare it with a true associated type rather than a typealias)</div><br class=""><div class="">Associated types preserve <i class="">static</i> type information. The compiler refuses to let you perform operations on protocols with associated types that would throw that information away. You can't get around that check in today's language.</div><div class=""><br class=""></div><div class="">Jordan</div></body></html>