3

So I have two arrays

var arrayOne:Array<protocol<P1,P2>>
var arrayTwo:Array<P1>

Where P1 and P2 are protocols.

Question is how to make downcasting operation

arrayTwo = arrayOne as Array<P1>

What i get from Xcode is:

Cannot convert value of type 'Array<protocol<P1, P2>>' to specified type 'Array<P1>'

2 Answers 2

1

You need to cast the elements of the array, not the array itself.

arrayTwo = arrayOne.map { $0 as P1 }

Or as MartinR stated, there is even no need to cast the element.

arrayTwo = arrayOne.map { $0 }
Sign up to request clarification or add additional context in comments.

12 Comments

Interestingly, even assignment through the "identity map" with arrayTwo = arrayOne.map { $0 } makes the code compile. This is strange because upcasting the entire array does work for sub/superclasses, as in stackoverflow.com/questions/30169839/….
@MartinR the type of Element is known from arrayTwo declaration, so i think this is 'normal'
@user3441734 It might be "normal", but is it definitely not intuitive. Which is what Swift is supposed to be. There is also no conceivable reason for this to require a map.
@MartinR hm... may be this is cleaner to see 'typealias U = P1 var arrayTwo: Array<U> = arrayOne.map{ (e) -> U in e }' it so no casting, but conversion
@user3441734 how is that cleaner? As MartinR stated, casting is not even needed.
|
0
protocol P1{}
struct A: P1{}
// everybody knows, that
let a = A()
// (1)
let p: P1 = a
// or (2)
let p1 = a as P1

let arr: Array<A> = []
// has type
print(arr.dynamicType) // Array<A>
// (3) the array is converted to different type here !!
let arr1: Array<P1> = arr.map{ $0 }
print(arr1.dynamicType) // Array<P1>

// arr and arr1 are differnet types!!!
// the elements of arr2 can be down casted as in (1) or (2)
// (3) is just an equivalent of
typealias U = P1
let arr3: Array<U> = arr.map { (element) -> U in
    element as U
}
print(arr3.dynamicType) // Array<P1>


// the array must be converted, all the elements are down casted in arr3 from A to P1
// the compiler knows the type so ii do the job like in lines (1) or (2)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.