Eternam
Eternam

Reputation: 23

Swift: array of structs implementing protocol

I can't understand why I can't pass an array of structs (which implement a protocol) to a function expecting an array of things that conform to that protocol.

I get a compile error at: r.setDataToRender(toRender) --> Cannot convert value of type [Process] to expected argument type [MyType].

What I can do is to create an array [MyType] and append each element of toRender and pass that new array instead, but that seems inefficient.

//: Playground - noun: a place where people can play
typealias MyType = protocol<Nameable, Countable>

protocol Nameable {
    func getName() -> String
}

protocol Countable {
    func getCount() -> Int
}

struct Process : MyType {
    let processName: String?
    let count: Int?

    init(name:String, number: Int) {processName = name; count = number}
    func getCount() -> Int {return count!}
    func getName() -> String {return processName!}
}

class Renderer {
    var data  = [MyType]()

    func setDataToRender(d: [MyType]) {
        data = d
    }

    func setOneProcessToRender(d: Process) {
        var temp = [MyType]()
        temp.append(d)
        data = temp
    }
}

var toRender = [Process]()
toRender.append(Process(name: "pro1",number: 3))

let r = Renderer()
r.setOneProcessToRender(Process(name: "pro2",number: 5)) // OK
r.setDataToRender(toRender) // KO

var str = "Hello, Stackoverflow!"

Upvotes: 2

Views: 514

Answers (1)

joern
joern

Reputation: 27620

It works if you change it to this:

var toRender = [MyType]()
toRender.append(Process(name: "pro1",number: 3))

Your function setDataToRender is expecting an array of types MyType. When you instantiated your array you typed it to Process. Although Process implements MyType it is not identical to MyType. So you have to create toRender as an array of types MyType to be able to send it to setDataToRender.

Upvotes: 1

Related Questions