Here's my favorite WTF: https://christiantietze.de/posts/2020/01/string-index-offset...
Here's my favorite WTF: https://christiantietze.de/posts/2020/01/string-index-offset...
A simple fix in the doc seems to solve the confusion:
"Returns an index that is the specified distance from the given index, unless that distance is beyond a given limiting index [in which case it returns nil]".
It does say "returns an index ... unless ..". So yeah, a bit too terse. But with is the issue with the API?
// /!\ Warning! Do not use in production! /!\
let s = "Swift"
if let i = s.index(s.startIndex, offsetBy: 5, limitedBy: s.endIndex) {
print(s[i])
}
"What does it print? Nothing, you hope?"Seriously? 'print(s[nil])' should print nothing? How about 'let c = s[nil]'. Should that just silently pass? That is the runtime error, btw. It won't even get to print(). (Valid to question the entirely non-informative error, however.)
The problem is that it returns non-nil, but the _limit_ is broken in this case: using s.endIndex as a limit means you can get non-nil but bogus indices returned. And yes, this is the fault of the docs for using a broken last arg to the API, but there's no really clean way to use this API as designed, afaict. At least not if you want to limit to "end of string" as opposed to "some index into the string that I already know to be valid".
let s = "Swift"
if !s.isEmpty,
let index = s.index(s.startIndex, offsetBy: 5, limitedBy: s.index(before: s.endIndex)) {
print(s[index])
}
I am sure the equivalent code in other languages, barring Python, is going to be similarly verbose. let s = "Swift"
print(s.index(s.startIndex, offsetBy: 4, limitedBy: s.endIndex))
print(s.index(s.startIndex, offsetBy: 5, limitedBy: s.endIndex))
print(s.index(s.startIndex, offsetBy: 6, limitedBy: s.endIndex))
outputs: Optional(Swift.String.Index(_rawBits: 262401))
Optional(Swift.String.Index(_rawBits: 327681)) <- this is unexpected
nil