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

Posted

技术标签:

【中文标题】在 Swift 中继承具有自己类型和存储属性的数组【英文标题】:Inherit array with own type and stored properties in Swift 【发布时间】:2022-01-07 23:54:52 【问题描述】:

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

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

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

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

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] 创建继承以包含存储的属性?

【问题讨论】:

使用组合而不是继承,创建一个将数组作为(私有)属性的新类,然后添加其他属性和函数来访问/修改数组。如果你不需要对它进行那种控制,你也可以让数组公开。 @JoakimDanielson - 这是一种可能性,尽管在这种情况下(直接)不提供内置数组方法 如果您想包含自己的存储属性,我认为您没有那么多其他选择 是否有类似数组的协议来创建类? 是的,请查看 Array 的文档,看看它符合什么。 【参考方案1】:

为您的案例使用组合可能会更好。

...但是如果您真正想要的是自定义类型的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)
    

【讨论】:

此时,使用组合策略可能比重新实现大多数数组方法更好 @Smally 是的,没错。 Array 的大部分功能已经在 Collection 协议的扩展中实现。取决于您需要什么 Array 方法。我在上面发布的内容是您有义务实施的所有内容。其他一切都是可选的。

以上是关于在 Swift 中继承具有自己类型和存储属性的数组的主要内容,如果未能解决你的问题,请参考以下文章

在mongodb中继承一个集合的属性[重复]

java中继承和多态

如何在 Swift 中继承 UITableViewController

是否不需要在 Swift 3 中继承 NSManagedObject ?

JavaScript中继承的多种方式和优缺点

JavaScript中继承方式详解