It is checked. You can see the source code here.
I am skeptical of this proposal. I think the need for legitimate use cases (i.e. combining a check that an index is in range with fetching of the element) is fairly rare. OTOH the defensive use of this technique i.e. "just in case the logic of my code is totally wrong, I don't want to trap" is highly dubious IMO. We should discourage this kind of use of optionals, for the same reason neverNil!
should be favored over neverNil ?? butJustInCaseItIs
.
Then again, given the legitimate "combined bounds check and fetch" use case, there's grounds to add it for readability/expressibility; and we've just been through a round of "but what if people misuse this feature" discussion with the python interop proposal so we probably shouldn't have that again... I think the best solution to that is to give it an appropriate argument label such as Collection.subscript(ifInBounds:)
.
I'm strongly opposed to making it a function. It should match the regular trapping subscript, and definitely shouldn't be more prominent. Discoverability issues are more of a tooling question than a driving reason to deviate from the current language idioms.
If we do add a nil-returning subscript (or indeed even if we don't), we should also add a parallel Collection.subscript(unchecked:)
customization point, which collections can override to access the underlying elements without bounds checks. This would be an unsafe operation (so perhaps the argument label should be unsafe:
, but I think I prefer unchecked:
).
This is important for the implementation of other operations that also do this checking and want to avoid duplicate checks. For example, the default implementation of Collection.subscript(ifInBounds:)
would check the bounds, and if not nil
, call the unchecked implementation. Slice
, which ought to check if the index is in the bounds of the slice not just the base, could also use this.