Быстрая проверка соответствия стандартного протокола

96
7

Я пытаюсь расширить класс Swift Array со следующей функцией:


func containsObjectIdenticalTo(obj: T) -> Bool {
// objectPassingTest returns the first object passing the test
return objectPassingTest { x in x == obj }
}

По-видимому, это не будет компилироваться, поскольку компилятор еще не знает, если == реализован для типа T. Затем я меняю код на


func containsObjectIdenticalTo(obj: T) -> Bool {
return objectPassingTest {
x in
assert(x is Equatable && obj is Equatable)
return (x as Equatable) == (obj as Equatable)
} != nil
}

Это тоже не работает, поскольку соответствие с Equatable невозможно проверить (поскольку Equatable не был определен с помощью @obj) !


Любые мысли об этом? Было бы неплохо, если бы какой-то способ прямо утверждать, если T соответствует Equatable, но я нигде не читал. Swift кажется менее динамичным, чем Obj-C в этих материалах.


UPDATE:
Пробовал это предложение, и он не работает (не знаю точно, для чего <T: Equatable>, он компилируется).


func containsObjectIdenticalTo<T: Equatable>(obj: T) -> Bool {
var x = self[0]
var y = self[0]
return x == y // Error here
}

спросил(а) 2021-01-19T19:35:31+03:00 2 месяца, 3 недели назад
1
Решение
97

Укажите, что T должна быть равнозначной в сигнатуре метода:

func containsObjectIdenticalTo<T: Equatable>(obj: T) -> Bool {/*...*/}

ответил(а) 2021-01-19T19:35:31+03:00 2 месяца, 3 недели назад
62

Как насчет:


func containsObjectIdenticalTo<T : Equatable>(obj: T) -> Bool {
... etc ...
}

ответил(а) 2021-01-19T19:35:31+03:00 2 месяца, 3 недели назад
61

В конце концов, я обратился к этому решению


func containsObjectIdenticalTo<U: Equatable>(obj: U) -> Bool {
return objectPassingTest({
x in
return x as U == obj
}) != nil
}

Не может быть лучшим (т.е. безопасным). Но он отлично работает.

ответил(а) 2021-01-19T19:35:31+03:00 2 месяца, 3 недели назад
62

Я получил это от ExSwift: https://github.com/pNre/ExSwift


 func contains <T: Equatable> (items: T...) -> Bool {
return items.all { self.indexOf($0) >= 0 }
}

func indexOf <U: Equatable> (item: U) -> Int? {
if item is Element {
if let found = find(reinterpretCast(self) as Array<U>, item) {
return found
}

return nil
}

return nil
}

func all (call: (Element) -> Bool) -> Bool {
for item in self {
if !call(item) {
return false
}
}

return true
}

возможно, вы можете попробовать его

ответил(а) 2021-01-19T19:35:31+03:00 2 месяца, 3 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема