Я пытаюсь создать «безопасный» оператор индексации для коллекции - такой, который игнорирует части диапазонов, выходящие за пределы доступных индексов для коллекции.
Желаемое поведение - возвращать Slice во всех случаях; когда нет перекрытия между диапазоном нижнего индекса и диапазоном коллекции, и должен быть возвращен пустой массив.
Это казалось простым расширением техники, представленной в этом ответе. документация оператора индекса коллекции очень проста:
subscript(bounds: Range<Self.Index>) -> Slice<Self> { get }
Но когда я использую те же типы в своей функции-оболочке, я получаю следующее:
Копировать / вставить версию:
extension Collection where Indices.Iterator.Element == Index {
subscript(safe bounds: Range<Self.Index>) -> Slice<Self> {
let empty = Slice(base: self, bounds: (startIndex..<startIndex))
guard bounds.lowerBound < endIndex else { return empty }
guard bounds.upperBound >= startIndex else { return empty }
let lo = Swift.max(startIndex, bounds.lowerBound)
let hi = Swift.min(endIndex, bounds.upperBound)
return self[lo..<hi]
}
}
Почему я не могу подписать коллекцию таким образом? Почему компилятор подтверждает, что я использую правильный тип Range<Self.Index>
(указанный в документации), но все же считаю это ошибкой?
where Indices.Iterator.Element == Index
не используется в вашем настраиваемом подстрочном индексе. Вы можете рассмотреть возможность переноса его в неограниченное расширениеCollection
(при условии, что у вас есть другие методы, которые используют ограничение в вашем текущем). - person Hamish   schedule 08.12.2016self[lo..<hi]
- этоSelf.SubSequence
, поэтому вы не можете вернуть его там, где ожидаетсяSlice<Self>
. Конечно, сообщение об ошибке (как это часто бывает) вводит в заблуждение. - person matt   schedule 08.12.2016Indices
в этом ответе, и вы можете видеть, что он не дает никаких обещаний относительно типа своих элементов (поэтому компилятор не может узнать, являются ли ониEquatable
, и, следовательно, можете ли вы использоватьcontains(_:)
метод на.indices
). - person Hamish   schedule 09.12.2016where
, я надеюсь, что команда stdlib добавит один вIndices
, который ограничивает егоIterator.Element
типомIndex
(потому что это то, что это, набор индексов), что позволит вам избавиться от с ограничением расширения. До тех пор в моем первом комментарии я предлагал иметь одно неограниченное расширениеCollection
для ранжированного нижнего индекса, а затем иметь другое расширениеCollection
, на этот раз сwhere Indices.Iterator.Element == Index
для единственного нижнего индекса. - person Hamish   schedule 09.12.2016