Не удается вызвать ‘swapAt’ со списком аргументов типа ‘(Int, Int)’

#swift

#swift

Вопрос:

Пожалуйста, рассмотрите следующее:

 extension MutableCollection where Self:BidirectionalCollection, Element: Equatable {

    mutating func moveRight(_ value: Element){

        for i in (0..<self.count) {

            if (self[self.index(self.startIndex, offsetBy: i)] == value){
                swapAt(0, 5)
            }
        }
    }
}
  

Xcode показывает мне ошибку в swapAt(0,5) . Почему? swapAt — это метод, для которого требуется 2 целых числа (индекса), и я предоставляю 2 целочисленных значения.

введите описание изображения здесь

Ответ №1:

На самом деле нет, MutableCollection.swapAt не определен так, чтобы принимать два Int , он определен в терминах Index из MutableCollection :

 swapAt(Self.Index, Self.Index)
  

Поэтому вы не можете просто использовать Int , если не добавите

 Index == Int
  

ограничение вашего объявления, делающее его:

 extension MutableCollection where Self: BidirectionalCollection, Element: Equatable, Index == Int {
    mutating func moveRight(_ value: Element){
        for i in (0..<self.count) {
            if (self[self.index(self.startIndex, offsetBy: i)] == value){
                swapAt(0, 5)
            }
        }
    }
}
  

Если вы не хотите ограничиваться целочисленными индексами, вам следует начать с замены итерации из 0 ..< count итерацией по индексам:

 for i in indices {
    if (self[i] == value) {
       // do swap
       ...
    }
}
  

Комментарии:

1. хорошо, хорошо, пожалуйста, взгляните на мой обновленный вопрос. Почему произошел такой промах в начале?

2. @EvgeniyKleban Вы смотрите на Array , а не на MutableCollection . Index == Int Поэтому swapAt массив имеет значение on Array , которое определяется с помощью Int . Это сработало бы, если бы вы расширяли Array напрямую.

3. Если OP не требуется обращаться к коллекции reversed и / или к последнему свойству коллекции, ограничение на BidirectionalCollection здесь бессмысленно.

Ответ №2:

Снимок экрана выполняется для swapAt for Array , а не MutableCollection . В отличие от массивов, коллекции могут иметь нецелочисленный индекс (например, String).

Вы могли бы использовать Self.Index этот способ:

 extension MutableCollection where Self:BidirectionalCollection, Element: Equatable {
    mutating func moveRight(_ value: Element){
        for i in (0..<self.count) {
            if self[index(startIndex, offsetBy: i)] == value {
                swapAt(startIndex, index(startIndex, offsetBy: 5))
            }
        }
    }
}
  

Или как предложено в комментариях Султан и Лео Дабус :

 extension MutableCollection where Self: BidirectionalCollection, Element: Equatable {
    mutating func moveRight(_ value: Element) {
        for i in indices where self[i] == value {
            swapAt(startIndex, index(startIndex, offsetBy: 5))
        }
    }
}
  

Комментарии:

1. На самом деле, вероятно, нам следует повторить indices в первую очередь 🙂