characters swift string swift4

swift - characters - ''subíndice'' no está disponible: no se puede subordinar Cadena con un CountableClosedRange<Int>, vea el comentario de la documentación para discusión



swift 4 string append (3)

En Swift 4, recibo este error cuando intento tomar una Substring de una String usando la sintaxis de los subíndices.

''subíndice'' no está disponible: no se puede subordinar Cadena con un CountableClosedRange, vea el comentario de la documentación para discusión

Por ejemplo:

let myString: String = "foobar" let mySubstring: Substring = myString[1..<3]

Dos preguntas:

  1. ¿Cómo puedo resolver este error?
  2. ¿Dónde está "el comentario de documentación para discusión" al que se hizo referencia en el error?

  1. ¿Cómo puedo resolver este error?

Este error significa que no puede usar un Int en el formato de subíndice; tiene que usar un String.Index, que puede inicializar con un codificado.

let myString: String = "foobar" let lowerBound = String.Index.init(encodedOffset: 1) let upperBound = String.Index.init(encodedOffset: 3) let mySubstring: Substring = myString[lowerBound..<upperBound]

  1. ¿Dónde está "el comentario de documentación para discusión" al que se hizo referencia en el error?

Está en GitHub, en el repositorio de la Biblioteca Swift Standard, en un archivo llamado UnavailableStringAPIs.swift.gyb en el fondo de un archivador cerrado con llave en un baño en desuso con un cartel en la puerta que dice "Cuidado con el Leopardo". enlazar


  1. Si desea utilizar subíndices en cadenas como "palindrome"[1..<3] y "palindrome"[1...3] , use estas extensiones.

Swift 4

extension String { subscript (bounds: CountableClosedRange<Int>) -> String { let start = index(startIndex, offsetBy: bounds.lowerBound) let end = index(startIndex, offsetBy: bounds.upperBound) return String(self[start...end]) } subscript (bounds: CountableRange<Int>) -> String { let start = index(startIndex, offsetBy: bounds.lowerBound) let end = index(startIndex, offsetBy: bounds.upperBound) return String(self[start..<end]) } }

Swift 3

Para Swift 3, reemplace con return self[start...end] y return self[start..<end] .

  1. Apple no construyó esto en el lenguaje Swift porque la definición de un ''carácter'' depende de cómo se codifique la Cadena. Un carácter puede ser de 8 a 64 bits, y el valor predeterminado suele ser UTF-16. Puede especificar otras codificaciones de cadena en String.Index .

Esta es la documentación a la que se refiere el error de Xcode.

Más sobre codificaciones de cadenas como UTF-8 y UTF-16


Tu pregunta (y tu respuesta) tiene 2 problemas:

Subscribir una cadena con Int nunca ha estado disponible en la biblioteca estándar de Swift. Este código ha sido inválido mientras Swift exista:

let mySubstring: Substring = myString[1..<3]

El nuevo String.Index(encodedOffset: ) devuelve un índice en codificación UTF-16 (16 bits). La cadena de Swift utiliza Cluster Grapheme extendido , que puede tomar entre 8 y 64 bits para almacenar un carácter. Emojis hacen muy buena demostración:

let myString = "🇺🇸🇨🇦🇬🇧🇫🇷" let lowerBound = String.Index(encodedOffset: 1) let upperBound = String.Index(encodedOffset: 3) let mySubstring = myString[lowerBound..<upperBound] // Expected: Canadian and UK flags // Actual : gibberish print(mySubstring)

De hecho, obtener el String.Index no ha cambiado en absoluto en Swift 4, para bien o para mal:

let myString = "🇺🇸🇨🇦🇬🇧🇫🇷" let lowerBound = myString.index(myString.startIndex, offsetBy: 1) let upperBound = myString.index(myString.startIndex, offsetBy: 3) let mySubstring = myString[lowerBound..<upperBound] print(mySubstring)