[swift-users] returning an array of Protocol-conforming objects from a function
Jordan Rose
jordan_rose at apple.com
Tue Jan 26 12:56:34 CST 2016
The problem is that an array of protocols is stored using a different representation from an array of plain structs (or classes, for that matter). Converting from [Float] to [MyProtocol] is therefore an O(N) operation, while a normal upcast between class types is O(1) (by sharing the underlying storage).
This does keep tripping people up, though, so maybe an explicit "as" should be considered good enough. The typical workarounds are either to use "as [MyProtocol]" to begin with (as Trent mentioned) or to use 'map' to build a new array ("return a.map { $0 }").
(Any change in this space would need to go through the Swift Evolution Process <https://github.com/apple/swift-evolution/blob/master/process.md>.)
Best,
Jordan
> On Jan 25, 2016, at 19:58, Ryan Walklin via swift-users <swift-users at swift.org> wrote:
>
> Hi Austin,
>
> Thanks for your reply. Sorry you’re right, my struct types don’t work if they are in in existing array of type [MyType] as below.
>
> I’ve been trying to work round it and found that with the following code:
>
> extension MyType: MyProtocol {}
>
> var array1: [MyType]
>
> fun foo() -> [MyProtocol] {
> return array1
> }
>
> func foo2 -> [MyProtocol] {
> return [myType1, myType2]
> }
>
>
> The foo pattern fails, but the foo2 pattern works. My existing code with struct type was all of type foo2, so I didn’t appreciate the error. As you stay, still seems like a problem with type inference.
>
> Ryan
>
>> On 26 Jan 2016, at 2:47 PM, Austin Zheng <austinzheng at gmail.com <mailto:austinzheng at gmail.com>> wrote:
>>
>> Hi Ryan,
>>
>> Are you sure it works with user-defined struct types? I tried the following code, and got the same error:
>>
>> protocol MyProtocol {}
>>
>> struct Blah : MyProtocol { }
>>
>> func foo() -> [MyProtocol] {
>> let a = [Blah(), Blah()] as [Blah]
>> return a
>> }
>>
>> 'class Blah' works fine.
>>
>> Even so, this is not the behavior I would have expected. Perhaps someone else can explain why [T] can't be upcasted to [P] when T is a struct and T : P.
>>
>> Best,
>> Austin
>>
>>
>>> On Jan 25, 2016, at 7:36 PM, Ryan Walklin via swift-users <swift-users at swift.org <mailto:swift-users at swift.org>> wrote:
>>>
>>> Hi All,
>>>
>>> I have a function which returns a closure, which then returns an array of objects conforming to a protocol.
>>>
>>> ie.
>>>
>>> protocol MyProtocol {}
>>>
>>> extension Float: MyProtocol {}
>>> extension OtherType: MyProtocol {}
>>>
>>> When I try to return an array of Floats, I get the error “Cannot convert value of type '[Float]' to closure result type ‘[MyProtocol]”.
>>>
>>> Other struct-based types work fine.
>>>
>>> Is this not possible with standard library types?
>>>
>>> Regards,
>>>
>>> Ryan
>>> _______________________________________________
>>> 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
> https://lists.swift.org/mailman/listinfo/swift-users
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20160126/da322b4d/attachment.html>
More information about the swift-users
mailing list