One reason is the complexity issue written in the thread you referred.
Another reason is to hide the implementation details.
You may have read this article: Strings in Swift 2
Assume the string is as follows:
var str = "a\u{e9}\u{3042}\u{1f436}\u{1f1fa}\u{1f1f8}f"
(It seems the editor of the forums does not like emoji characters. See what's contained in `str` in the Playground.)
The string above contains 6 characters, but its internal representation may be something like this:
in utf16 index
[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]
0061 00e9 3042 d83d dc36 d83c ddfa d83c ddf8 0066 (end)
[0] [1] [2] [3]-----> [4]---------------> [5] [6]
in characters
If you want to get a substring with character range 3..<6, you need to collect utf16 code units 3..<10 .
let s = str.startIndex.advancedBy(3) calculates the internal utf16 index[3] by characters count
let s = s.advancedBy(3) calculates the internal utf16 index[10] (end of string) by characters count
The `str` may have other representation like utf8 or unicodeScalar, but using advancedBy, you need not to know the implementation details, and you can get the right position hidden inside String.Index.
But, knowing such things, I sometimes get really annoyed writing String handling codes in Swift.
I believe Swift team could provide many more convenience methods, without breaking the features like described above.
ADDITION:
You've already found some extensions for Swift String in that thread. Here is another:
extension String {
func indexByInt(index: Int) -> Index {
if index >= 0 {
return self.startIndex.advancedBy(index)
} else {
return self.endIndex.advancedBy(index)
}
}
func substringByInt(start: Int, _ end: Int? = nil) -> String {
let startIndex = self.indexByInt(start)
let endIndex = end != nil ? self.indexByInt(end!) : self.endIndex
if startIndex <= endIndex {
return self.substringWithRange(startIndex..<endIndex)
} else {
return ""
}
}
func substringByInt(range: Range<Int>) -> String {
return self.substringByInt(range.startIndex, range.endIndex)
}
}
str.substringByInt(2)
str.substringByInt(0, 4)
str.substringByInt(0, -2)
str.substringByInt(3..<6)
This example is not super-efficient. You can improve it, once you understand the basics of Swift String.