Swift protocol arrays

Hi



I have some struct objects that are heterogeneous like this


    struct Cat: Hashable {
       let name: String
       let catId: Int
    }
    struct SubCat: Hashable {
       let name: String
       let catId: Int
       let parentCatId: Int
    }


Now I have a tableView that needs to show either Cat or SubCat. My first choice was to extend both classes with a protocol :



  protocol Selectable {
        func asString() -> String
    }


and my struct became :



    struct Cat: Hashable, Selectable {
       let name: String
       let catId: Int
       func asString() -> {
          return self.name
      }
    }
    struct SubCat: Hashable, Selectable {
       let name: String
       let catId: Int
       let parentCatId: Int
       func asString() -> {
          return self.name
      }
    }


It worked so far.

I declared a [Selectable] object in my TableViewController, used asString() to populate my cells. Compiled like a charm.



But here's the thing. I've got a CatModel class and a SubCatModel class, each returning an array of each structs [Cats] and [SubCats]

When I try to assign the [Cat] array to the [Selectable] array, it does not compile. If I changed the return type of my [Cat] array to [Selectable], it does not compile.



Can anyone help me with this? I guess I'm missing something here.

Thanks.

Accepted Reply

I'm not sure why the casting doesn't work, but you can map array of Cats to array of Selectables.


let cats = [Cat(name: "One", catId: 0), Cat(name: "Two", catId: 2)]
let selectables = cats.map { $0 as Selectable }

Replies

I'm not sure why the casting doesn't work, but you can map array of Cats to array of Selectables.


let cats = [Cat(name: "One", catId: 0), Cat(name: "Two", catId: 2)]
let selectables = cats.map { $0 as Selectable }

That is actually what I've finished to do.

Other people had the same issue and filed a radar.

I'm just glad to see that I did not misinterpreted the Protocol Extension behavior 🙂

Thanks.