在 Swift 中继承具有自己类型和存储属性的数组

Inherit array with own type and stored properties in Swift

通常我有一个包含 MemoryComponent class 的数组(所以 [MemoryComponent])。我想将其重构为自定义数组 class,其元素类型为 MemoryComponent 并包含程序可以使用的存储属性。

我尝试创建一个扩展,但它不允许存储属性:

extension Array where Element: MemoryComponent {
    // ... no stored properties due to extension
}

我还尝试为数组创建另一个 class:

class StorageArray: Array<MemoryComponent> {
    // ... stored properties are possible
    // but there's an error because of this:
    // error: inheritance from non-protocol, non-class type 'Array<MemoryComponent>'
}

如何有效地从 [MemoryComponent] 创建继承以包含存储的属性?

您的情况最好使用组合。

...但是如果自定义类型的 Array 是您真正想要的,那么实际上有一个奇怪且不推荐的选项可以破解它。

您不能从 Array 继承,因为它是 struct。但是你可以实现 Collection 协议。

struct MemoryComponent {}

struct MemoryComponentsArray: Collection {
    
    // typealias all associatedTypes of `Collection` protocol
    typealias Element = MemoryComponent
    typealias Index = Array<Element>.Index
    typealias SubSequence = Array<Element>.SubSequence
    typealias Iterator = Array<Element>.Iterator
    typealias Indices = Array<Element>.Indices
    
    /// Your real data storage
    private let internalArray: Array<Element>
    
    /**
     Create any custom initializers you need
     */
    init(_ arrayLiteral: [Element]) {
        self.internalArray = arrayLiteral
    }
    
    // Implement `Collection` protocol core stuff
    // By referencing to internal array
    
    var startIndex: Index { internalArray.startIndex }
    var endIndex: Index { internalArray.endIndex }
    func makeIterator() -> Iterator { internalArray.makeIterator() }
    subscript(position: Index) -> Element { internalArray[position] }
    subscript(bounds: Range<Index>) -> SubSequence { internalArray[bounds] }
    var indices: Indices { internalArray.indices }
    var isEmpty: Bool { internalArray.isEmpty }
    var count: Int { internalArray.count }
    func index(_ i: Index, offsetBy distance: Int) -> Index {
        internalArray.index(i, offsetBy: distance)
    }
    func index(_ i: Index, offsetBy distance: Int, limitedBy limit: Index) -> Index? {
        internalArray.index(i, offsetBy: distance, limitedBy: limit)
    }
    func distance(from start: Index, to end: Index) -> Int {
        internalArray.distance(from: start, to: end)
    }
    func index(after i: Index) -> Index {
        internalArray.index(after: i)
    }
    func formIndex(after i: inout Index) {
        internalArray.formIndex(after: &i)
    }
}