Reputation: 5729
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
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