The Swift Array Design (2014)
github.com
github.com
Two things stood out to me here as being really nice for someone coming from C++:
- Implicit upcasting to convert `[Derived]` to `[Base]` in O(1).
- Checked conversions convert `[T]` to `[U]?` in O(N) via `a as [U]` in O(n).
These are both operations I've manually written the C++ code to do, because there's no ergonomic way to do it with `std::vector`.
E.g., given an array of Animal, you’d like to see if you can convert it to an array of Dog. Neither the compiler nor the runtime stores information on the array itself to say “it just so happens that the concrete Animal type of all the things I hold is [Dog/Cat/a mix of both],” so you have to go through the elements one by one.
The upcast is type sound, unlike Java, but at the cost of an extra indirection, and a big hit for the first mutation after upcast. I would have been tempted to instead just have immutable array references that could be freely upcast, but this is also an elegant and safe solution.
Why would elements being classes change this?
Wouldn't an array of class elements only hold pointers to those instances, so it wouldn't be different than "an array of Swift value types" at that regard (the extra dereference would only be needed after getting the element pointer out of the array).
It's more the other way around: having non-objects allows things to change.
Being able to transparently bridge between Objective-C and Swift is very valuable, particularly because the vast majority of library/framework code is written in Objective-C.
So Swift Arrays are designed to be bridgeable to NSArray whenever possible, for example by simply pointing to an NSArray as their backing store. NSArrays can be non-contiguous, largely due to them not really being arrays in the strict sense, but more like Smalltalk OrderedCollections, meaning you can, for example, add and remove elements from the front.
However, non-object Swift types cannot be stored in an NSArray and would thus never be expected in Objective-C code. Therefore, there is no need to bridge those, meaning that you can use different kinds of backing store.