Hidden feature: subscript
You’re more of a video kind of person? I’ve got you covered! Here’s a video with the same content than this article 🍿
There’s a good chance that you’ve already used subscripts at one point or another.
But did you know that they have a hidden feature?
Let’s start with a quick recap on how a subscript
works!
A subscript
is actually very similar to a method!
The two main differences are that you declare it by using the keyword subscript
instead of func
and that it doesn’t have a name:
This absence of a name is on purpose, because subscripts are called with a special syntax that uses square brackets:
Most of the time, we use simple subscripts that take only a single argument.
But it’s actually possible to define more complex subscripts!
For instance, Dictionary
comes with a subscript
that allows you to provide a defaultValue
that will be returned if the Dictionary
doesn’t contain the given key
.
Even better, you can also define an overload of an existing subscript
, but with a different external name for the argument.
We can use this approach to define this alternate subscript
on Collection
, which takes an index of the Collection
just like the regular subscript
already does, but this time with an added external argument name.
And then we can call this alternate subscript
instead of the regular one by using the external argument name:
That’s all for this article, I hope you’ve enjoyed learning this new trick!
Here’s the code if you want to experiment with it:
extension Array {
subscript(index: Int) -> Element {
// ...
}
}
let numbers = [0, 2, 4]
numbers[2] // returns 4
extension Dictionary {
subscript(
key: Key,
default defaultValue: @autoclosure () -> Value
) -> Value {
// ...
}
}
let dictionary = [ "zero": 0, "one": 1, "two": 2]
dictionary["two", default: -1] // returns 2
dictionary["three", default: -1] // returns -1
extension Collection {
subscript (safe index: Index) -> Element? {
return indices.contains(index) ? self[index] : nil
}
}
let data = [1, 3, 4]
data[10] // will crash 💥
data[safe: 10] // returns nil