2016-12-10 4 views
1

Рассмотрим следующий код:тип протокола не может быть реализован

protocol Color { 
    var color: UIColor { get } 
} 

struct Ball : Color { 
    var color: UIColor 
} 

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

Это работает, и результаты в:

Ball(color: UIExtendedGrayColorSpace 1 1) 

Теперь я хотел бы сделать функцию в протоколе, что дано массив цветов, возвращает массив элементов (шары, или любой другой тип, который соответствует Color) с этим цветом:

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

     return coloredItems 
    } 
} 

, а затем:

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

Я не могу понять, что положить в скобки. Так, например (не каламбур), если я попробовать:

coloredItems.append(Color(color: item)) 

ошибка:

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

Затем я добавил метод инициализации к протоколу, а ошибка изменен на:

protocol type 'Color' cannot be instantiated 

Как это исправить?

+1

Вы пытаетесь создать экземпляр протокола 'Color (цвет: элемент)', который не возможно. – shallowThought

+0

Итак, какие-нибудь идеи, как изменить это? – Koen

+0

Непонятно, что именно вы ожидаете от вывода функции 'multipleColors'. Какова проблема, которую вы пытаетесь решить здесь? – Hamish

ответ

1

Вы пытаетесь создать экземпляр протокола Color(color: item), что невозможно.

Найдите одно из возможных общих вариантов ниже. Пока я не нашел нестатического (приятного) решения.

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) 

Печать:

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

Мне нравится это решение, и он примет его, так как он отвечает на вопрос. Тем не менее, 'Ball' также имеет больше свойств, таких как' size' (которые я пропустил для ясности), и их также нужно размножать на 'colorItems'. – Koen

+0

Я рассматривал это как довольно теоретический пример. На практике используйте класс. Вы хотите знать, есть ли 'alicesBall === bobsBall'. Также я бы удалил 'Color'. Создать 'class ColoredItem {var color: UIColor func multipleColors() ...'. И подкласс это. – shallowThought

+1

Также вы можете использовать функцию 'copy' и использовать ее:' T.copy() 'вместо' T.init() '. – shallowThought

Смежные вопросы