[swift-users] Weird protocol behaviour.

Zhao Xin owenzx at gmail.com
Fri Dec 23 06:46:56 CST 2016


You mis-labelled you problem in your original email.

    let x = X() as P // this does not compile. Why?
    foo(x)

The issue is not in line ` let x = X() as P`. It is in line ` foo(x)`, `x's
type is P`, but `foo(:)` request a parameter type of `A`, not `P`.

`func foo<A:P>(_ x:A) {}` means, `x` must be `A`, and `A` conforms `P`. But
not all `P`s are `A`.

Zhaoxin

On Fri, Dec 23, 2016 at 5:26 PM, Adrian Zubarev via swift-users <
swift-users at swift.org> wrote:

> Whoops, wait a second. Correcting my self here. Copied the wrong url.
>
> Here is the proposal I meant. LINK
> <https://github.com/apple/swift-evolution/blob/cd9d8b3f1923d16f4381c23d3d335d88d83e32cd/proposals/0126-refactor-metatypes.md>
>
>
>
> --
> Adrian Zubarev
> Sent with Airmail
>
> Am 23. Dezember 2016 um 09:57:49, Adrian Zubarev (
> adrian.zubarev at devandartist.com) schrieb:
>
>
>    -
>
>    What are you trying to solve here?
>    -
>
>    Do you heavily rely on what A can be?
>    -
>
>    Can’t you just write func foo(_ x: P) {} (here P is an *existential*
>    like [in some future] Any<P>)?!
>    -
>
>    AnyObject is for classes, but you’d get the same result changing X to
>    a class ;)
>
> If you want scratch the surface of what happens to protocols in a generic
> context, you could read our proposal about meta types here
> <https://github.com/apple/swift-evolution/blob/91725ee83fa34c81942a634dcdfa9d2441fbd853/proposals/0126-refactor-metatypes-repurpose-t-dot-self-and-mirror.md>
> .
>
>
> --
> Adrian Zubarev
> Sent with Airmail
>
> Am 23. Dezember 2016 um 09:43:34, Mikhail Seriukov via swift-users (
> swift-users at swift.org) schrieb:
>
> No it does not.
>> You have made a type out of the parameter. It’s no longer a protocol.
>> IMO the failure here is to understand the difference between a type and a
>> protocol.
>> A type (even if empty) is always a combination of storage with functions
>> (that are assumed to work on the data in storage)
>> A protocol is just a definition of functions without the accompanying
>> data.
>>
>
> I see your point.
> But actually when I write it as  `let x = X() as P` I really mean that I
> want `x` to be `AnyObject` but conforming to P, not just protocol itself.
> Is it even possible to downcast it this way?
>
> 2016-12-23 14:51 GMT+07:00 Marinus van der Lugt <rien at starbase55.com>:
>
>>
>> On 22 Dec 2016, at 22:43, Howard Lovatt <howard.lovatt at gmail.com> wrote:
>>
>> The following variation works:
>>
>> protocol P {}
>>
>> class P1:P {}
>>
>> class X:P1 {}
>>
>> func foo<A:P>(_ x:A) {}
>>
>> func bar() {
>>     //let x = X() // this compiles
>>     let x = X() as P1 // this does not compile. Why?
>>     foo(x)
>> }
>>
>> Which adds credence to the bug theory.
>>
>>
>>
>> No it does not.
>> You have made a type out of the parameter. It’s no longer a protocol.
>> IMO the failure here is to understand the difference between a type and a
>> protocol.
>> A type (even if empty) is always a combination of storage with functions
>> (that are assumed to work on the data in storage)
>> A protocol is just a definition of functions without the accompanying
>> data.
>>
>> Rien.
>>
>>
>>
>>
>> Note two changes: 1. two levels of inheritance and 2. change to classes.
>> If you do two levels using protocols it doesn't work if you use either
>> classes or structs.
>>
>>
>>   -- Howard.
>>
>> On 23 December 2016 at 07:29, Kevin Nattinger <swift at nattinger.net>
>> wrote:
>>
>>> I recall seeing a request on the -evolution list for something like `T
>>> := X` to indicate it could be X itself or anything inheriting /
>>> implementing it, so it’s certainly known behavior, if not desired. IMO it’s
>>> a bug and `:` should be fixed to include the root type, whether or not that
>>> requires a discussion on -evolution.
>>>
>>> On Dec 22, 2016, at 2:17 PM, Howard Lovatt via swift-users <
>>> swift-users at swift.org> wrote:
>>>
>>> I suspect a compiler bug since A is a P. The equivalent in Java works:
>>>
>>> interface P {}
>>> class X implements P {}
>>>
>>> <A extends P> void foo(A x) {}
>>>
>>> void bar() {
>>>     final P x = new X();
>>>     foo(x);
>>> }
>>>
>>> -- Howard.
>>>
>>> On 23 Dec 2016, at 3:19 am, Rien via swift-users <swift-users at swift.org>
>>> wrote:
>>>
>>> IMO the error message says it all:
>>>
>>> Playground execution failed: error: MyPlayground8.playground:9:5: error:
>>> cannot invoke 'foo' with an argument list of type '(P)'
>>>    foo(x)
>>>    ^
>>>
>>> MyPlayground8.playground:9:5: note: expected an argument list of type
>>> '(A)'
>>>    foo(x)
>>>    ^
>>>
>>> I.e. you are passing in a protocol while the function is specified for a
>>> type.
>>> Said other way: On which data do you expect the protocol to operate?
>>>
>>> Regards,
>>> Rien
>>>
>>> Site: http://balancingrock.nl
>>> Blog: http://swiftrien.blogspot.com
>>> Github: http://github.com/Swiftrien
>>> Project: http://swiftfire.nl
>>>
>>>
>>>
>>>
>>> On 22 Dec 2016, at 17:05, Mikhail Seriukov via swift-users <
>>> swift-users at swift.org> wrote:
>>>
>>>
>>> Hello community! I' wondering if somebody can explain this to me.
>>>
>>> Please take look at the snippet.
>>>
>>>
>>> protocol P {}
>>>
>>> struct X:P {}
>>>
>>>
>>> func foo<A:P>(_ x:A) {}
>>>
>>>
>>> func bar() {
>>>
>>>    //let x = X() // this compiles
>>>
>>>    let x = X() as P // this does not compile. Why?
>>>
>>>    foo(x)
>>>
>>> }
>>>
>>>
>>> I expect the both cases to work though. But only first works? And I do
>>> not understand why.
>>>
>>> My coworkers said that it is a compiler bug, but I'm not shure it is.
>>>
>>> Thanks for the help.
>>>
>>> _______________________________________________
>>>
>>> swift-users mailing list
>>>
>>> swift-users at swift.org
>>>
>>> https://lists.swift.org/mailman/listinfo/swift-users
>>>
>>>
>>> _______________________________________________
>>> swift-users mailing list
>>> swift-users at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-users
>>>
>>> _______________________________________________
>>> swift-users mailing list
>>> swift-users at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-users
>>>
>>>
>>>
>>
>>
> _______________________________________________
> swift-users mailing list
> swift-users at swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
>
>
> _______________________________________________
> swift-users mailing list
> 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/20161223/24b4bf5e/attachment.html>


More information about the swift-users mailing list