Swift Generics проблема
Прямо сейчас я хочу видеть, включен ли объект в Array
так:
func isIncluded<U:Comparable>(isIncluded : U) -> Bool
{
for item in self
{
if (item == isIncluded)
{
return true
}
}
return false
}
Если вы заметили, что эта функция принадлежит Array
расширение. Проблема в том, если добавить это к этому:
extension Array{
}
Я получаю следующую ошибку:
Не удалось найти перегрузку для '==', которая принимает предоставленные аргументы
Я понимаю, что, возможно, мне нужно будет сказать, какие объекты должны быть внутри Array
вот так: T[] <T.GeneratorType.Element: Comparable>
, Но это не так хорошо работает:
Скрепленный блок выписок является неиспользованным закрытием
Неноминальный тип 'T[]' не может быть расширен
Ожидаемое '{' в расширении
3 ответа
С Swift нам нужно подумать, есть ли функция, которая может добиться цели - вне методов класса.
Так же, как в нашем случае здесь:
contains(theArray, theItem)
Вы можете попробовать это на детской площадке:
let a = [1, 2, 3, 4, 5]
contains(a, 3)
contains(a, 6)
Я обнаружил множество этих функций, щелкнув cmd по символу Swift (например, Array), а затем просмотрев этот файл (который представляется глобальным файлом, содержащим все объявления для общих классов и функций Swift).
Вот небольшое расширение, которое добавит метод "содержащий" ко всем массивам:
extension Array {
func contains<T: Equatable>(item: T) -> Bool {
for i in self {
if item == (i as T) { return true }
}
return false
}
}
Чтобы добавить, проблема в том, что T уже определено, и определение массива T не соответствует Equatable. Вы можете либо выполнить то, что вы хотите, разыгрывая (например, принятый ответ) и рискуя недействительным приведением, либо вы можете передать делегата, где не требуется разыгрывание.
Рассмотрите возможность изменения следующим образом:
extension Array {
func contains(comparator: (T)->Bool) -> Bool {
for item in self {
if comparator(item) {
return true
}
}
return false
}
}
Пример использования:
class Test {
func arrayContains(){
var test: Int[] = [0,1,3,4,5]
//should be true
var exists = test.contains({(item)->Bool in item == 0});
}
}
Не сказать, что это невозможно, но я еще не видел способа расширить структуры или классы, чтобы наложить условия на оригинальные дженерики, например, чтобы гарантировать Equatable
или же Comparable
на массиве. Однако для вашей конкретной проблемы вместо расширения вы можете сделать что-то вроде следующего:
var arr = [1, 2, 3]
var isIncluded : Bool = arr.bridgeToObjectiveC().doesContain(1)