I am new in Swift. I have a base class:
class foo{}
I want to implement a foo collection class:
class foos: Array{}
Swift's Array type is a structure, and in Swift, base classes must be actual classes (that is, class Foo) and not structures.
So you cannot do what you are trying to do via inheritance from Array, unfortunately. You could, however, store the array as a field within your class and forward methods to it, possibly implementing any protocols you want to support, et cetera.
In Swift, Array is a struct, not a class. To have a class that is an array subclass, you will need to use NSArray, its Objective-C counterpart.
For example,
class Foo: NSArray{}
In Swift 2.x you can use a protocol extension.
class Foo : Equatable {}
// you need to provide the Equatable functionality
func ==(leftFoo: Foo, rightFoo: Foo) -> Bool {
return ObjectIdentifier(leftFoo) == ObjectIdentifier(rightFoo)
}
extension Array where Element : Foo {}
protocol extensions provide "insert points" to extend classes that aren't classes, classes you don't own, etc.
You can create own array using RangeReplaceableCollection protocol.
import Foundation
struct Arr<T: Equatable>: RangeReplaceableCollection {
typealias Element = T
typealias Index = Int
typealias SubSequence = Arr<T>
typealias Indices = Range<Int>
fileprivate var array: Array<T>
var startIndex: Int { return array.startIndex }
var endIndex: Int { return array.endIndex }
var indices: Range<Int> { return array.indices }
func index(after i: Int) -> Int {
return array.index(after: i)
}
init() { array = [] }
}
// Instance Methods
extension Arr {
init<S>(_ elements: S) where S : Sequence, Arr.Element == S.Element {
array = Array<S.Element>(elements)
}
init(repeating repeatedValue: Arr.Element, count: Int) {
array = Array(repeating: repeatedValue, count: count)
}
}
// Instance Methods
extension Arr {
public mutating func append(_ newElement: Arr.Element) {
array.append(newElement)
}
public mutating func append<S>(contentsOf newElements: S) where S : Sequence, Arr.Element == S.Element {
array.append(contentsOf: newElements)
}
func filter(_ isIncluded: (Arr.Element) throws -> Bool) rethrows -> Arr {
let subArray = try array.filter(isIncluded)
return Arr(subArray)
}
public mutating func insert(_ newElement: Arr.Element, at i: Arr.Index) {
array.insert(newElement, at: i)
}
mutating func insert<S>(contentsOf newElements: S, at i: Arr.Index) where S : Collection, Arr.Element == S.Element {
array.insert(contentsOf: newElements, at: i)
}
mutating func popLast() -> Arr.Element? {
return array.popLast()
}
@discardableResult mutating func remove(at i: Arr.Index) -> Arr.Element {
return array.remove(at: i)
}
mutating func removeAll(keepingCapacity keepCapacity: Bool) {
array.removeAll()
}
mutating func removeAll(where shouldBeRemoved: (Arr.Element) throws -> Bool) rethrows {
try array.removeAll(where: shouldBeRemoved)
}
@discardableResult mutating func removeFirst() -> Arr.Element {
return array.removeFirst()
}
mutating func removeFirst(_ k: Int) {
array.removeFirst(k)
}
@discardableResult mutating func removeLast() -> Arr.Element {
return array.removeLast()
}
mutating func removeLast(_ k: Int) {
array.removeLast(k)
}
mutating func removeSubrange(_ bounds: Range<Int>) {
array.removeSubrange(bounds)
}
mutating func replaceSubrange<C, R>(_ subrange: R, with newElements: C) where C : Collection, R : RangeExpression, T == C.Element, Arr<T>.Index == R.Bound {
array.replaceSubrange(subrange, with: newElements)
}
mutating func reserveCapacity(_ n: Int) {
array.reserveCapacity(n)
}
}
// Subscripts
extension Arr {
subscript(bounds: Range<Arr.Index>) -> Arr.SubSequence {
get { return Arr(array[bounds]) }
}
subscript(bounds: Arr.Index) -> Arr.Element {
get { return array[bounds] }
set(value) { array[bounds] = value }
}
}
// Operator Functions
extension Arr {
static func + <Other>(lhs: Other, rhs: Arr) -> Arr where Other : Sequence, Arr.Element == Other.Element {
return Arr(lhs + rhs.array)
}
static func + <Other>(lhs: Arr, rhs: Other) -> Arr where Other : Sequence, Arr.Element == Other.Element{
return Arr(lhs.array + rhs)
}
static func + <Other>(lhs: Arr, rhs: Other) -> Arr where Other : RangeReplaceableCollection, Arr.Element == Other.Element {
return Arr(lhs.array + rhs)
}
static func + (lhs: Arr<T>, rhs: Arr<T>) -> Arr {
return Arr(lhs.array + rhs.array)
}
static func += <Other>(lhs: inout Arr, rhs: Other) where Other : Sequence, Arr.Element == Other.Element {
lhs.array += rhs
}
}
extension Arr: Equatable {
static func == (lhs: Arr<T>, rhs: Arr<T>) -> Bool {
return lhs.array == rhs.array
}
}
extension Arr: CustomStringConvertible {
var description: String { return "\(array)" }
}
// init
var array = Arr<Int>()
print(array)
array = Arr(repeating: 0, count: 5)
print(array)
array = Arr([1,2,3,4,5,6,7,8,9])
print(array)
// add
array.append(0)
print(array)
array.append(contentsOf: [5,5,5])
print(array)
// filter
array = array.filter { $0 < 7 }
print(array)
// map
let strings = array.map { "\($0)" }
print(strings)
// insert
array.insert(99, at: 5)
print(array)
array.insert(contentsOf: [2, 2, 2], at: 0)
print(array)
// pop
_ = array.popLast()
print(array)
_ = array.popFirst()
print(array)
// remove
array.removeFirst()
print(array)
array.removeFirst(3)
print(array)
array.remove(at: 2)
print(array)
array.removeLast()
print(array)
array.removeLast(5)
print(array)
array.removeAll { $0%2 == 0 }
print(array)
array = Arr([1,2,3,4,5,6,7,8,9,0])
array.removeSubrange(0...2)
print(array)
array.replaceSubrange(0...2, with: [0,0,0])
print(array)
array.removeAll()
print(array)
array = Arr([1,2,3,4,5,6,7,8,9,0])
print(array)
// subscript
print(array[0])
array[0] = 100
print(array)
print(array[1...4])
// operator functions
array = [1,2,3] + Arr([4,5,6])
print(array)
array = Arr([4,5,6]) + [1,2,3]
print(array)
array = Arr([1,2,3]) + Arr([4,5,6])
print(array)