在 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 中继承具有自己类型和存储属性的数组的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Swift 中继承 UITableViewController