<html><head><meta http-equiv="Content-Type" content="text/html charset=gb2312"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Thank you, Slava.</div><div class=""><br class=""></div><div class="">I will use the trick you provided.</div><div class="">And knowing that this bug has already been under tracking is a great comfort to me, really :)</div><div class=""><br class=""></div><div class="">Lincoln</div><br class=""><div><blockquote type="cite" class=""><div class="">在 2017年8月11日,上午11:29,Slava Pestov <<a href="mailto:spestov@apple.com" class="">spestov@apple.com</a>> 写道:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Aug 10, 2017, at 8:23 PM, Slava Pestov via swift-users <<a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div 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: <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></div></blockquote><div class=""><br class=""></div>I’m sorry, but this is nonsense. We don’t allow ‘Self’ to refer to the dynamic Self type yet.</div><div class=""><br class=""></div><div class="">You could do something like this I guess,</div><div class=""><br class=""></div><div class="">func cast<T, U>(from: T, to: U.Type) -> U {</div><div class=""> return from as! U</div><div class="">}</div><div class=""><br class=""></div><div class="">let copied = cast(from: super.copy(), to: type(of: self))</div><div class=""><br class=""></div><div class="">Slava</div><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""></div><div class="">Slava</div><div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Aug 10, 2017, at 8:16 PM, 吴君恺 via swift-users <<a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a>> 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 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;"> func copy() -> 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;"> .....</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;"> var color: UIColor?</span></div><div class=""><span class="" style="font-family: Menlo;"><br class=""></span></div><div class=""><font face="Menlo" class=""> required init() {}</font></div><div class=""><font face="Menlo" class=""> </font></div><div class=""><font face="Menlo" class=""> func copy() -> Self {</font></div><div class=""><font face="Menlo" class=""> let copied = type(of: self).init()</font></div><div class=""><font face="Menlo" class=""> copied.color = color</font></div><div class=""><font face="Menlo" class=""> return copied</font></div><div class=""><font face="Menlo" class=""> }</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=""> var radius: Float = 5</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class=""> func copy() -> Self {</font></div><div class=""><font face="Menlo" class=""> let copied = super.copy() </font></div><div class=""><font face="Menlo" class=""> copied.radius = radius </font><span class="" style="font-family: Menlo;"> // compilation error</span></div><div class=""><font face="Menlo" class=""> return copied</font></div><div class=""><font face="Menlo" class=""> }</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. </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=""><a href="https://lists.swift.org/mailman/listinfo/swift-users" class="">https://lists.swift.org/mailman/listinfo/swift-users</a><br class=""></div></blockquote></div><br class=""></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=""><a href="https://lists.swift.org/mailman/listinfo/swift-users" class="">https://lists.swift.org/mailman/listinfo/swift-users</a><br class=""></div></blockquote></div><br class=""></div></div></blockquote></div><br class=""></body></html>