koen
koen

Reputation: 5729

Protocol type cannot be instantiated

Consider the following code:

protocol Color {
    var color: UIColor { get }
}

struct Ball : Color {
    var color: UIColor
}

let ball = Ball(color: .white)
print(ball)

This works, and results in:

Ball(color: UIExtendedGrayColorSpace 1 1)

Now, I would like to make a function in the protocol, that given an array of colors, returns an array of items (balls, or any other type that conforms to Color) with that color:

extension Color {
    func multipleColors(colors: [UIColor]) -> [Color] {
       var coloredItems = [Color]()
       for item in colors {
        // What do I put here ???
       }

       return coloredItems
    }
}

and then:

let coloredBalls = ball.multipleColors(colors: [.red, .green, .blue])

I cannot figure out what to put inside the brackets. For instance (no pun), if I try:

coloredItems.append(Color(color: item))

the error is:

'Color' cannot be constructed because it has no accessible initializers

I then added an init method to the protocol, and the error changed to:

protocol type 'Color' cannot be instantiated

How do I fix this?

Upvotes: 1

Views: 8297

Answers (1)

shallowThought
shallowThought

Reputation: 19602

You are trying to create an instance of a protocol Color(color: item), which is not possible.

Find one possible generic solution below. I could not find a non-static (nice) solution so far.

protocol Color {
    var color: UIColor {get set}
    init(color: UIColor)
}

struct Ball : Color {
    var color: UIColor
}

extension Color {
    static func item<T:Color>(_ item: T, inColors colors: [UIColor]) -> [T] {
        var coloredItems = [T]()
        for color in colors {
            let newColoredItem = T.init(color: color)
            coloredItems.append(newColoredItem)
        }

        return coloredItems
    }
}

let ball = Ball(color: .white)
let coloredBalls = type(of:ball).item(ball, inColors: [.red, .green, .blue])

print(coloredBalls)

Prints:

[Ball(color: UIExtendedSRGBColorSpace 1 0 0 1), Ball(color: UIExtendedSRGBColorSpace 0 1 0 1), Ball(color: UIExtendedSRGBColorSpace 0 0 1 1)]

Upvotes: 3

Related Questions