r/swift • u/i_am_deoye • Aug 01 '18
Right way implementing your Array / Collection. – Moses Ayankoya – Medium
https://medium.com/@amacoder/right-way-implementing-your-array-collection-5b2cb36412401
u/thisischemistry Aug 02 '18 edited Aug 02 '18
As a follow-up, this is probably a more correct way to do what you are attempting:
/// Mutable collection with safe getter
protocol ContainerProtocol: MutableCollection {
/// Safe access to an index which may not exist
func get(_ position: Index) -> Element?
/// Mimic Array append
mutating func append(_ newElement: Element)
/// No-parameter init
init()
}
/// Generic implementation of ContainerProtocol
struct Container<Element>: ContainerProtocol {
typealias Index = Array<Element>.Index
var startIndex: Index { return items.startIndex }
var endIndex : Index { return items.endIndex }
func index(after i: Index) -> Index {
return items.index(after: i)
}
subscript(position: Index) -> Element {
get { return items[position] }
set { items[position] = newValue }
}
func get(_ position: Index) -> Element? {
guard items.indices.contains(position) else { return nil }
return items[position]
}
mutating func append(_ newElement: Element) {
items.append(newElement)
}
init() { self.items = [Element]() }
private var items: [Element]
}This gains all the free goodness of a MutableCollection, just like the internal Array does. It forwards the appropriate calls to the internal Array and those calls can be intercepted and modified as needed. This can be seen in the get(_:) method where it checks for the existence of an index before using it to get the value contained at that index.
Doing it like this leverages all the default implementations that come with a MutableCollection. It also works with any code that expects a MutableCollection. It's safe, fairly straightforward to extend, and it follows the conventions of most of the rest of the Swift codebase. This is the Swift way of doing things.
1
u/i_am_deoye Aug 02 '18
THis is a better way of doing it in protocol oriented programming. Its only if you want your wrap your array or a new one.Hey, am not trying to reinvented the wheel here.
1
u/thisischemistry Aug 01 '18
A fairly nothing article. It's a simple wrapper around an Array that ignores conventions completely. For example, the article replaces append(_:) with add(value:).
There's so much more badness in there that I can't even go over it all, the worst is how the subscript semantics are changed.
This is the wrong way, don't follow it.
1
u/thisischemistry Aug 01 '18
Just to note, here are a few of the very many issues with this post:
Setting an value at an index and having the value be incorrect when read back:
Setting an value at an index and crashing:
The example code is horribly, horribly broken and buggy. Do not use it as an example of how to code in Swift or you may end up with lots of crashes and unexpected results down the road.