我是Swift的新手。我有一个基类:
class foo{}
我想实现一个foo集合类:
class foos: Array<foo>{}
但编译器抱怨:
继承自非协议,非类型的'Array'
我尝试了其他语法(例如[foo]
和NSMutableArray<foo>
),但没有一个通过编译器检查。
这应该很简单,但我整天用Google搜索,无法弄明白。有谁知道它是否可能,如果是,正确的语法?
答案 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)
您可以使用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)