DevAndArtist DevAndArtist - 7 months ago 25
Swift Question

Swift 2.2: cannot convert value of type '[B]' to specified type '[A]'

I'm officially confused why this is not working (there isn't much to explain here):

protocol A {

var value: Int { get set }
}

struct B: A {

var value: Int
}

let array: [B] = [B(value: 10)]

let singleAValue: A = array[0] // extracting works as expected

var protocolArray: [A] = []
protocolArray.append(singleAValue) // we can put the value inside the `protocolArray` without problems
print(protocolArray)

let newProtocolArray: [A] = array // but why does this conversion not work?

Answer

The array of the protocol type has a different memory representation than an array of B structs. Because an array of A can contain many different types of objects, the compiler has to create an indirection (a wrapper around the elements in the array) to ensure that they all have the same size.

Since this conversion is potentially costly (if the source array is large), the compiler forces you to make it explicit by mapping over the source array. You can write either this:

let newProtocolArray = array.map { $0 as A }

or this:

let newProtocolArray: [A] = array.map { $0 }

Both are equivalent.