How to subclass an array class in Swift?

前端 未结 4 1783
予麋鹿
予麋鹿 2021-02-20 00:05

I am new in Swift. I have a base class:

class foo{}

I want to implement a foo collection class:

class foos: Array{}
         


        
相关标签:
4条回答
  • 2021-02-20 00:16

    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.

    0 讨论(0)
  • 2021-02-20 00:18

    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{}
    
    0 讨论(0)
  • 2021-02-20 00:25

    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.

    0 讨论(0)
  • 2021-02-20 00:25

    Details

    • Xcode 10.1 (10B61)
    • Swift 4.2

    Idea

    You can create own array using RangeReplaceableCollection protocol.

    Sample

    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)" }
    }
    

    Usage

    // 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)
    
    0 讨论(0)
提交回复
热议问题