如何在Swift中子类化数组类?

时间:2014-10-09 23:12:00

标签: arrays inheritance swift

我是Swift的新手。我有一个基类:

class foo{}

我想实现一个foo集合类:

class foos: Array<foo>{}

但编译器抱怨:

  

继承自非协议,非类型的'Array'

我尝试了其他语法(例如[foo]NSMutableArray<foo>),但没有一个通过编译器检查。

这应该很简单,但我整天用Google搜索,无法弄明白。有谁知道它是否可能,如果是,正确的语法?

4 个答案:

答案 0 :(得分:15)

Swift的Array类型是一个结构,在Swift中,基类必须是实际的类(即class Foo),而不是结构。

不幸的是,你不能通过Array的继承做你想做的事。但是,您可以将数组存储为类中的字段并将方法转发给它,可能实现您要支持的任何协议等等。

答案 1 :(得分:5)

在Swift中,Array是一个结构,而不是一个类。要拥有一个数组子类的类,您需要使用NSArray,它的Objective-C对应物。

例如,

class Foo: NSArray{}

答案 2 :(得分:3)

在Swift 2.x中,您可以使用协议扩展。

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 {}

协议扩展提供&#34;插入点&#34;扩展不属于班级的班级,你不拥有的班级等等。

答案 3 :(得分:0)

详细信息

  • Xcode 10.1(10B61)
  • 迅速4.2

想法

您可以使用RangeReplaceableCollection协议创建自己的数组。

样本

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)