Я пытаюсь создать простой протокол, который сообщает, находится ли объект в состоянии «включен» или «выключен». Интерпретация того, что это такое, зависит от реализующего объекта. Для UISwitch
это то, включен или выключен переключатель (да). Для UIButton
это может быть то, находится ли кнопка в состоянии selected
или нет. Для Car
это может быть то, включен двигатель автомобиля или нет, или даже движется он или нет. Поэтому я решил создать этот простой протокол:
protocol OnOffRepresentable {
func isInOnState() -> Bool
func isInOffState() -> Bool
}
Теперь я могу расширить вышеупомянутые элементы управления пользовательским интерфейсом следующим образом:
extension UISwitch: OnOffRepresentable {
func isInOnState() -> Bool { return on }
func isInOffState() -> Bool { return !on }
}
extension UIButton: OnOffRepresentable {
func isInOnState() -> Bool { return selected }
func isInOffState() -> Bool { return !selected }
}
Теперь я могу создать массив таких объектов и перебрать его, проверяя, включены они или нет:
let booleanControls: [OnOffRepresentable] = [UISwitch(), UIButton()]
booleanControls.forEach { print($0.isInOnState()) }
Большой! Теперь я хочу создать словарь, который сопоставляет эти элементы управления с UILabel
, чтобы я мог изменить текст метки, связанной с элементом управления, когда элемент управления меняет состояние. Итак, я иду объявить свой словарь:
var toggleToLabelMapper: [OnOffRepresentable : UILabel] = [:]
// error: type 'OnOffRepresentable' does not conform to protocol 'Hashable'
Ой! Верно! Я такой глупый. Хорошо, позвольте мне просто обновить протокол, используя композицию протокола (в конце концов, все элементы управления, которые я хочу здесь использовать, - это Hashable: UISwitch, UIButton и т. Д.):
protocol OnOffRepresentable: Hashable {
func isInOnState() -> Bool
func isInOffState() -> Bool
}
Но теперь я получаю новый набор ошибок:
error: protocol 'OnOffRepresentable' can only be used as a generic constraint because it has Self or associated type requirements
error: using 'OnOffRepresentable' as a concrete type conforming to protocol 'Hashable' is not supported
Хорошо ... Итак, я копаюсь и ищу переполнение стека. Я нахожу много многообещающих статей, например Set и протоколы в Swift, Использование какого-либо протокола в качестве конкретного типа соответствие другому протоколу не поддерживается, и я вижу, что есть несколько замечательных статей на type erasure
, которые, кажется, именно то, что мне нужно: http://krakendev.io/blog/generic-protocols-and-их-недостатки, http://robnapier.net/erasure и https://realm.io/news/type-erased-wrappers-in-swift/ и это лишь некоторые из них.
Здесь я застрял. Я пробовал прочитать все это, и я попытался создать класс, который будет Hashable
и также будет соответствовать моему OnOffRepresentable
протоколу, но я не могу понять, как это все соединить.
MythicalType
был единственным протоколом, которому он пытался соответствовать. Поэтому, когда я пытаюсь заменитьMythicalType
прямо на мойOnOffRepresentable
, этого недостаточно. Не могу понять, как вставить в него частьHashable
. То же самое относится и к блогу Роба Нэпьера, ... может быть. ЕгоAnimal
протокол является общим дляFood
ассоциированного типа, но я тоже этим не занимаюсь. Примеры realm.io показались мне лучшими, ноSequenceType
также сильно отличается от моих конкретных потребностей. - person Tim Fuqua   schedule 20.08.2016