<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hi Lincoln,<div class=""><br class=""></div><div class="">This is a known issue with ‘super’ method calls:&nbsp;<a href="https://bugs.swift.org/browse/SR-1736" class="">https://bugs.swift.org/browse/SR-1736</a></div><div class=""><br class=""></div><div class="">A workaround is to cast the result of the supermethod call to Self explicitly:</div><div class=""><br class=""></div><div class="">let copied = super.copy() as! Self</div><div class=""><br class=""></div><div class="">Slava</div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Aug 10, 2017, at 8:16 PM, 吴君恺 via swift-users &lt;<a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=us-ascii" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Hi all,</div><div class=""><br class=""></div>here is the scenario, I want to implement a Copying protocol which can be used&nbsp;homogeneously<div class=""><br class=""></div><div class=""><span class="" style="font-family: Menlo;">protocol Copying {</span><br class="" style="font-family: Menlo;"><span class="" style="font-family: Menlo;">&nbsp; &nbsp; func copy() -&gt; Self</span><br class="" style="font-family: Menlo;"><span class="" style="font-family: Menlo;">}</span></div><div class=""><span class="" style="font-family: Menlo;"><br class=""></span></div><div class="">Because this protocol contains neither associated-type-requirements or self-requirements(requiring a method returning Self is different), it can surely be used homogeneously.</div><div class=""><br class=""></div><div class=""><div class=""><span class="" style="font-family: Menlo;">let objects: [Copying] = ....</span></div></div><div class=""><span class="" style="font-family: Menlo;">for copyable in objects {</span></div><div class=""><span class="" style="font-family: Menlo;">&nbsp; &nbsp; .....</span></div><div class=""><span class="" style="font-family: Menlo;">}</span></div><div class=""><br class=""></div><div class="">It will work if I make one of my base class conform to Copying</div><div class=""><br class=""></div><div class=""><font face="Menlo" class="">class Shape: Copying {</font></div><div class=""><span class="" style="font-family: Menlo;">&nbsp; &nbsp; var color: UIColor?</span></div><div class=""><span class="" style="font-family: Menlo;"><br class=""></span></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; required init() {}</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; func copy() -&gt; Self {</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; let copied = type(of: self).init()</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;copied.color = color</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; return copied</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; }</font></div><div class=""><font face="Menlo" class="">}</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class="">The implementation of `copy` above is forced by compiler to avoid any explicit specification of type `Shape`, so that the returning value will have a dynamic type, which is just what I want. Here, the type of `copied` is `Self`</div><div class=""><br class=""></div><div class="">However, if I try to make a subclass of Shape, I can't find a elegant way to implement this `copy` method in that subclass, the following code will not compile.</div><div class=""><br class=""></div><div class=""><font face="Menlo" class="">class Circle: Shape {</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; var radius: Float = 5</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; func copy() -&gt; Self {</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; let copied = super.copy()&nbsp;</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; copied.radius = radius &nbsp; &nbsp;</font><span class="" style="font-family: Menlo;">&nbsp;// compilation error</span></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; return copied</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; }</font></div><div class=""><font face="Menlo" class="">}</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class="">The compiler will complain that `copied` has no property `radius`. It turns out that calling copy() on super will yield a value of type Shape, rather than Self.&nbsp;</div><div class=""><br class=""></div><div class="">Swift now forbids explicit conversion to `Self` (I totally agree with this rule), and will automatically allow `Self` to be treated as a specific type in some circumstances. But for this case, I wonder whether this is the correct behavior or a bug? Why calling `super.copy()` not be able to get a `Self`?</div><div class=""><br class=""></div><div class="">I did find a work-around for this problem afterwards, but this question really haunts me...</div><div class=""><br class=""></div><div class="">Cheers,</div><div class="">Lincoln.</div></div>_______________________________________________<br class="">swift-users mailing list<br class=""><a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-users<br class=""></div></blockquote></div><br class=""></div></body></html>