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)