[swift-users] Question with calling a method which returns `Self` on super
吴君恺
wjk_buaa at 163.com
Thu Aug 10 22:42:57 CDT 2017
Thank you, Slava.
I will use the trick you provided.
And knowing that this bug has already been under tracking is a great comfort to me, really :)
Lincoln
> 在 2017年8月11日,上午11:29,Slava Pestov <spestov at apple.com> 写道:
>
>
>> On Aug 10, 2017, at 8:23 PM, Slava Pestov via swift-users <swift-users at swift.org <mailto:swift-users at swift.org>> wrote:
>>
>> Hi Lincoln,
>>
>> This is a known issue with ‘super’ method calls: https://bugs.swift.org/browse/SR-1736 <https://bugs.swift.org/browse/SR-1736>
>>
>> A workaround is to cast the result of the supermethod call to Self explicitly:
>>
>> let copied = super.copy() as! Self
>
> I’m sorry, but this is nonsense. We don’t allow ‘Self’ to refer to the dynamic Self type yet.
>
> You could do something like this I guess,
>
> func cast<T, U>(from: T, to: U.Type) -> U {
> return from as! U
> }
>
> let copied = cast(from: super.copy(), to: type(of: self))
>
> Slava
>
>>
>> Slava
>>
>>> On Aug 10, 2017, at 8:16 PM, 吴君恺 via swift-users <swift-users at swift.org <mailto:swift-users at swift.org>> wrote:
>>>
>>> Hi all,
>>>
>>> here is the scenario, I want to implement a Copying protocol which can be used homogeneously
>>>
>>> protocol Copying {
>>> func copy() -> Self
>>> }
>>>
>>> Because this protocol contains neither associated-type-requirements or self-requirements(requiring a method returning Self is different), it can surely be used homogeneously.
>>>
>>> let objects: [Copying] = ....
>>> for copyable in objects {
>>> .....
>>> }
>>>
>>> It will work if I make one of my base class conform to Copying
>>>
>>> class Shape: Copying {
>>> var color: UIColor?
>>>
>>> required init() {}
>>>
>>> func copy() -> Self {
>>> let copied = type(of: self).init()
>>> copied.color = color
>>> return copied
>>> }
>>> }
>>>
>>> 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`
>>>
>>> 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.
>>>
>>> class Circle: Shape {
>>> var radius: Float = 5
>>>
>>> func copy() -> Self {
>>> let copied = super.copy()
>>> copied.radius = radius // compilation error
>>> return copied
>>> }
>>> }
>>>
>>> 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.
>>>
>>> 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`?
>>>
>>> I did find a work-around for this problem afterwards, but this question really haunts me...
>>>
>>> Cheers,
>>> Lincoln.
>>> _______________________________________________
>>> swift-users mailing list
>>> swift-users at swift.org <mailto:swift-users at swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-users <https://lists.swift.org/mailman/listinfo/swift-users>
>>
>> _______________________________________________
>> swift-users mailing list
>> swift-users at swift.org <mailto:swift-users at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-users
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20170811/d930ceb9/attachment.html>
More information about the swift-users
mailing list