ios - the - xcode kits
El tipo ''String.Index'' no cumple con el protocolo ''IntegerLiteralConvertible'' (3)
En la versión beta 4, el manejo del índice String.Index de Swift volvió a cambiar: ahora no puede proporcionar un Int
cuando se espera un String.Index
. La forma de manejarlo es creando el String.Index
que necesita usando el método de advance
:
if !name.isEmpty {
var splitted: [String] = name.componentsSeparatedByString(" ")
for curPart in splitted {
if !curPart.isEmpty {
acronym += curPart.substringToIndex(advance(curPart.startIndex, 1))
}
}
if countElements(acronym) > 2 {
acronym = acronym.substringToIndex(advance(acronym.startIndex, 2))
}
}
Todo esto se basa en asegurarse de que las cadenas Unicode se manejen correctamente, ya que los diferentes caracteres Unicode pueden tener diferentes tamaños, la indexación de enteros puros ocultaría el hecho de que las cadenas no son de acceso aleatorio.
Con Beta 3 todo funcionó bien, ahora recibo un error extraño, y no tengo ni idea de cómo solucionarlo. Probé todas las soluciones para problemas similares.
Aquí está mi código:
if !name.isEmpty {
var splitted: [String] = name.componentsSeparatedByString(" ")
for curPart in splitted {
if !curPart.isEmpty {
acronym += curPart.substringToIndex(1) //Error
}
}
if (acronym as NSString).length > 2 {
acronym = acronym.substringToIndex(2) //Error
}
}
Ambas líneas marcadas me dieron el mismo error:
El tipo ''String.Index'' no cumple con el protocolo ''IntegerLiteralConvertible''
¿Alguien me puede ayudar? ¿O es Beta 4 con errores? ¡Gracias!
La noción de Swift de componentes de cadena e iteración ha cambiado en Beta 4. En la guía , vemos:
Cada instancia del tipo de carácter de Swift representa un único grupo de grafemas extendidos. Un grupo de grafemas extendidos es una secuencia de uno o más escalares de Unicode que (cuando se combinan) producen un solo carácter legible para el ser humano.
Esto tiene algunos efectos secundarios interesantes:
let str1 = "abc"
let str2 = "/u{20DD}def"
countElements(str1) // 3
countElements(str2) // 4
countElements(str1+str2) // 6 ≠ 3+4 !!!
Esto se debe a que c
y /u{20DD}
combinan para formar c⃝. También note que estamos usando countElements
. Para calcular la longitud de la cadena, Swift en realidad tiene que iterar a través de toda la cadena y averiguar dónde están las divisiones de grafemas reales, por lo que lleva O (n) tiempo.
También podemos ver el efecto en diferentes codificaciones:
Array((str1+str2).utf8) // [97, 98, 99, 226, 131, 157, 100, 101, 102]
Array((str1+str2).utf16) // [97, 98, 99, 8413, 100, 101, 102]
Otro problema, como dice su error, es que el IndexType
String
ya no es convertible de un literal entero: no puede realizar un acceso aleatorio en la cadena especificando un desplazamiento. En su lugar, puede usar startIndex
y advance
para avanzar una cierta distancia en la cadena, por ejemplo, str[str.startIndex]
o str[advance(str.startIndex, distance)]
.
O puedes definir tus propias funciones de ayuda mientras tanto:
func at<C: Collection>(c: C, i: C.IndexType.DistanceType) -> C.GeneratorType.Element {
return c[advance(c.startIndex, i)]
}
func take<C: protocol<Collection, Sliceable>>(c: C, n: C.IndexType.DistanceType) -> C.SliceType {
return c[c.startIndex..<advance(c.startIndex, n)]
}
at(str1+str2, 3) // d
take(str1+str2, 2) // ab
Obviamente, hay algunas mejoras que podrían (y probablemente se harán) en futuras actualizaciones. Es posible que desee presentar un error con sus preocupaciones. A largo plazo, el soporte correcto de los grupos de grafemas probablemente fue una buena decisión, pero entretanto hace que el acceso a las cadenas sea un poco más doloroso mientras tanto.
Para Swift 2.0
Usando el ejemplo anterior:
curPart.substringToIndex(curPart.startIndex.advancedBy(1))