Вы не можете заставить тип @objc
соответствовать Equatable. У Equatable есть требование к Себе. Протоколы Objective- C не могут express самостоятельного требования.
Ваша функция ==
может использоваться, но она не приводит к тому, что тип соответствует Equatable. Это просто означает, что вы можете оценить item == item
. Вы не можете, однако, вызвать items.contain(item)
, так как Itemable не соответствует Equatable. То, что вы можете сделать, это вызвать items.contains{$0 == item}
, поскольку для этого просто необходима функция ==
, а не Equatable. И, конечно, вы можете реализовать пользовательский метод .contains
для [Itemable]
, если хотите. Но это все равно не будет Equatable.
Для вашего примера я считаю, что вы хотите полностью избавиться от ==
и использовать это:
guard let itemIndex = items.index(where: { $0.aProperty == item.aProperty }) else {
Если вы сделаете это a конечно, вы можете добавить расширение на [Itemable]
(не проверено):
extension Array where Element: Itemable {
func index(of element: Element) -> Int? {
firstIndex(where: { $0.aProperty == element.aProperty })
}
}
Тогда ваш оригинальный код будет в порядке.
Несколько не связано с вашим вопросом: возможно, это упрощенный код, но будьте очень осторожны с такого рода реализацией ==
. Во-первых, ==
всегда должен проверять все видимые свойства. Если, например, aProperty
является просто идентификатором, то это опасный способ реализовать ==
. Когда две вещи равны (как в Obj C, так и в Swift), ожидается, что они взаимозаменяемы во всех контекстах. Если вы когда-нибудь заботитесь о том, какой у вас есть, они на самом деле не «равны».
Кроме того, когда две вещи равны, они должны иметь одинаковое значение ha sh (и если они равны, они должен иметь тот же га sh).
См. Документацию по В соответствии с Equatable Protocol для правил. Хотя ==
технически не подразумевает Equatable, использование его сбивает с толку, если вы не имеете в виду Equatable.