Приветствую! Есть несколько функций, которые хотелось бы реализовать в виде extension как для Array, так и для ArraySlice. Чтобы не пришлось копипастить один и тот же код функций, хотелось бы одновременно расширить Array и ArraySlice. Как это можно сделать? В лоб прописать extension Array, ArraySlice - не получилось.
Extension Array & ArraySlice
Расширить протокол (общий для Array и ArraySlice) Collection:
extension Collection where Element == Int {
func myPrint() {
print(self)
}
}
var arr = [1, 2, 3]
arr.myPrint()
arr[1...].myPrint()
Спасибо. Добавил еще вот эти субскрипты, чтобы можно было отбирать элементы внутри функций внутри расширения:
subscript(index: Int) -> MyStruct {
return Array(self)[index]
}
subscript(range: CountableClosedRange<Int>) -> [MyStruct] {
return Array(self)[range]
}
Теперь получается обращаться к элементу/ам так: self[0] или self[1…2]. Но self[1…] не работает - Cannot subscript a value of type 'Self' with an index of type 'CountablePartialRangeFrom<Int>'
. Непринципиально, но может есть какое-то более правильное решение?
Переопределять сабскрипты плохая идея.
Если будете писать прям в лоб, то он будет вызывать сам себя до бесконечности:
extension Collection where Index == Int, Element == String {
subscript(range: CountablePartialRangeFrom<Index>) -> [Element] {
print(range)
return Array(self[range])
}
}
var arr = ["A", "B", "C"]
print(arr[1...])
Что бы это заработало нужно внутри вашего сабскрипта вызывать встроенный, для этого нужно указать тип возвращаемого значения:
extension Collection where Index == Int, Element == String {
subscript(range: CountablePartialRangeFrom<Index>) -> [Element] {
let result: SubSequence = self[range]
return Array(result)
}
}
var arr = ["A", "B", "C"]
print(arr[1...])
Но лучше пишите методы их проще запомнить и методы имеют названия, чем себя самодокументируют
extension Collection where Index == Int, Element == String {
func get(_ range: CountablePartialRangeFrom<Index>) -> [Element] {
return Array(self[range])
}
}
var arr = ["A", "B", "C"]
print(arr.get(1...))
В моем случае лучше не через метод, а через сабскрипты, например myStruct[0…1].isHigher - isHigher рассчитываемая переменная Bool, которая принимает массив и делает выводы:)
Получился вот такой код, все работает нормально:
extension Collection where Index == Int, Element == MyStruct {
subscript(index: Index) -> Element? {
return indices.contains(index) ? self[index] : nil
}
subscript(range: CountableClosedRange<Index>) -> [Element]? {
guard indices.contains(range.lowerBound), indices.contains(range.upperBound) else { return nil }
let subSequence: SubSequence = self[range]
return Array(subSequence)
}
subscript(range: CountablePartialRangeFrom<Index>) -> [Element]? {
guard indices.contains(range.lowerBound) else { return nil }
let subSequence: SubSequence = self[range]
return Array(subSequence)
}
//...
}
Вот только не пойму, почему первый сабскрипт никогда не вызывается. Если в массиве 100 элементов, а я вызову myStruct[200], то вместо nil получу run time error.