0
import Foundation

class A: NSObject {

}

class B: A {

}

let array = [B(),B(),B(),B()]

array as? [A] //this does not works

B() as? A // this works
Hamish
  • 78,605
  • 19
  • 187
  • 280
  • 2
    Why would you need to do this? You can pass an array of `B` to anything that expects an array of `A` – dan May 16 '16 at 20:44

2 Answers2

1

as? is a conditional downcasting operation (which can fail, and therefore returns an optional) – and you're trying to upcast (which can never fail, and therefore you can do freely).

You therefore can just use as in order to freely upcast the array – or rely on type inference, as Casey notes.

let arrayOfB = [B(),B(),B(),B()]

let arrayOfA = arrayOfB as [A] // cast of [B] to [A] via 'as'

let explicitArrayOfA : [A] = arrayOfB // cast of [B] to [A] via inference of explicit type 

func somethingThatExpectsA(a:[A]) {...}

somethingThatExpectsA(arrayOfB) // implicit conversion of [B] to [A]

Although the compiler's error of A is not a subtype of B is certainly unhelpful in the context. A more suitable error (or maybe just a warning) could be 'as?' will always succeed in casting '[B]' to '[A]' – did you mean to use 'as'?.

You should also note that for your example:

B() as? A // this works

You'll get a compiler warning saying Conditional cast from 'B' to 'A' always succeeds. Although why you get a compiler warning, rather than error for this – I can't say. I suspect it's due to the special way in which array casting happens.

Community
  • 1
  • 1
Hamish
  • 78,605
  • 19
  • 187
  • 280
1

Because B is an A, you can drop the conditional cast and

let thing = array as [A]

Or declare the destination as the desired type and forget about casting

let thing : [A] = array
Casey Fleser
  • 5,707
  • 1
  • 32
  • 43