Reputation: 3627
I'm attempting to create a FIFO array in swift. I want to create something that acts like this:
var Arr = FixedFIFOArray<Int>(maxSize:3)
Arr.append(1) //Arr = [1]
Arr.append(2) //Arr = [1,2]
Arr.append(3) //Arr = [1,2,3]
Arr.append(4) //Arr = [2,3,4] <- the max size is fixed to 3, so any
additional values added remove old values
Other than this behavior, it should act like an array: allow slicing, indexing, iterating in for
loops, etc.
In any other language, this would be a job for subclassing. We aren't changing much, just adding an initializer and amending a function or two. However, in Swift, we can't subclass array
. What is the best way to do this? Do I need to implement every protocol that array
implements, and just pass the associated functions off to an array? Something like this:
struct FixedFIFOArray<T> {
var _maxSize: Int
var _array: [T] = []
init(maxSize: Int) {
self._maxSize = maxSize
}
}
extension FixedFIFOArray : Collection {
//...
}
extension FixedFIFOArray : RandomAccessCollection {
//...
}
extension FixedFIFOArray : Sequence {
//...
}
// etc...
This seems like a lot of work to do something so simple. What am I missing?
Upvotes: 4
Views: 2993
Reputation: 539745
It is not as bad as it seems, because many protocol requirements have default implementations. Unfortunately I do not have the perfect recipe to find a "minimal" implementation.
Some information can be found in the
RandomAccessCollection
documentation
where some methods are marked as "Required. Default implementation provided."
You can also start with an empty implementation extension FixedFIFOArray : RandomAccessCollection {}
and study the error messages or try the Fix-its.
With "Jump to Definiton" in the Xcode editor one can inspect the protocol definitions and extension methods.
In your case it turned out that it suffices to implement
startIndex
, endIndex
, and subscript
:
extension FixedFIFOArray : RandomAccessCollection {
var startIndex: Int {
return _array.startIndex
}
var endIndex: Int {
return _array.endIndex
}
subscript(i: Int) -> T {
return _array[i]
}
}
Or, if you need a read-write subscript:
subscript(i: Int) -> T {
get {
return _array[i]
}
set {
_array[i] = newValue
}
}
Upvotes: 1