2

Here is some setup code to explain what is happening:

protocol CanJump{
    func jump()
}

struct Dog: CanJump{
    func jump(){
        print("yay jump")
    }
}

struct Cat: CanJump{
    func jump(){
        print("nothx")
    }
}

let d = [Dog()]
let c = Cat()

This does not work:

let thingsThatCanJump: [CanJump] = d 

Cannot convert value of type [Dog] to specified type [CanJump]

This does work:

let thingsThatCanJump: [CanJump] = [c]

A disgusting workaround that I've come up with is:

let thingsThatCanJump: [CanJump] = d.map({$0 as CanJump})

Can someone explain why this is happening?

I'm guessing this has something to do with the compiler not completely evaluating types and conformance.

ciauri
  • 513
  • 5
  • 13
  • 1
    FYI: let d = [Dog() as CanJump] works a s well – LoVo May 13 '16 at 09:10
  • 1
    It's a consequence of the fact that generics are invariant in Swift. [See this Q&A for more info](http://stackoverflow.com/questions/37188580/why-isnt-somestruct-convertible-to-any). Although note that you only encounter this problem with an array of structs, not classes. – Hamish May 13 '16 at 13:38
  • @originaluser2: Thank you! This is the answer I was looking for. – ciauri May 13 '16 at 20:18

2 Answers2

1

This is happening as you let d is actually type of [Dog] and swift is quite strict about type safety.

This fix this you can do following:

let d: [CanJump] = [Dog()]

Hope this helps

Andrey Kozlov
  • 221
  • 1
  • 2
0

It turns out that @originaluser2 already answered this question. You can see their detailed explanation here:

Why isn't [SomeStruct] convertible to [Any]?

Community
  • 1
  • 1
ciauri
  • 513
  • 5
  • 13