Pergunta

If I have a string:

let str = "Hello world"

It seems quite reasonable to be able to extract a character:

let thirdChar = str[3]

However, that's not legal. Instead, I have to use the extremely obtuse syntax:

let thirdChar = str[str.index(str.startIndex, offsetBy: 2)]

Similarly, why isn't str[0..<3] or str[0...2] legal? The intent is clear.

It's easy enough to create extensions to String that support those expressions:

extension String {

  //Allow string[Int] subscripting
  subscript(index: Int) -> Character {
    return self[self.index(self.startIndex, offsetBy: index)]
  }

  //Allow open ranges like `string[0..<n]`
  subscript(range: Range<Int>) -> Substring {
    let start = self.index(self.startIndex, offsetBy: range.lowerBound)
    let end = self.index(self.startIndex, offsetBy: range.upperBound)
    return self[start..<end]
  }

  //Allow closed integer range subscripting like `string[0...n]`
  subscript(range: ClosedRange<Int>) -> Substring {
    let start = self.index(self.startIndex, offsetBy: range.lowerBound)
    let end = self.index(self.startIndex, offsetBy: range.upperBound)
    return self[start...end]
  }
}

Shouldn't that be part of the language? Seems like a no-brainer.

Foi útil?

Solução

Swift strings are made of characters. Characters can be made of any number of Unicode code points. If you have a very long string, and you want to access the one-millionth Character, you'd have to traverse the whole one million Character string, because you have no idea how many codepoints you have.

For very good reasons, Apple doesn't want to make highly inefficient functionality part of the language. And why would you want to get the third character of "Hello, world"? In practice, that's not something you ever want. You might want "the characters before the comma", which you get by using character ranges.

Licenciado em: CC-BY-SA com atribuição
scroll top