'indice' est pas disponible: impossible d'indice en Chaîne de caractères avec un CountableClosedRange<Int>, voir le commentaire de documentation pour la discussion
Dans Swift 4, j'obtiens cette erreur quand j'essaie de prendre un Substring
d'un String
à l'aide de l'indice de la syntaxe.
'indice' est pas disponible: impossible d'indice en Chaîne de caractères avec un CountableClosedRange, voir le commentaire de documentation pour la discussion
Par exemple:
let myString: String = "foobar"
let mySubstring: Substring = myString[1..<3]
Deux questions:
- Comment puis-je résoudre ce problème?
- Où est "le commentaire de documentation pour la discussion" dont il était question dans l'erreur?
Pourquoi swift obtenir une sous-chaîne si compliqué?
OriginalL'auteur Barry Jones | 2017-08-04
Vous devez vous connecter pour publier un commentaire.
"palindrome"[1..<3]
et"palindrome"[1...3]
, l'utilisation de ces extensions.Swift 4
Swift 3
Pour Swift 3 remplacer avec
return self[start...end]
etreturn self[start..<end]
.String.Index
.Ceci est la documentation que Xcode erreur se réfère.
Plus sur la Chaîne de codages comme de l'UTF-8 et UTF-16
bounds.upperBound
au lieu debounds.upperBound - bounds.lowerBound
commeoffsetBy
paramètre.Compensation de la
bounds.upperBound - bounds.lowerBound
. Nous nous attendons à ce"Palindrome"[3..<4]
pour donner "je". Mais si nous essayonslet end = index(start, offsetBy: bounds.upperBound)
, nous allons obtenir "indr" à la place.Mon point ici est que vous voulez
startIndex
etendIndex
être des indices, c'est à dire les positions de caractères dans une chaîne, pas de distances entre les personnages.Désolé, s'il vous plaît jeter le commentaire précédent, j'ai accidentellement appuyé sur le bouton qui ne devraient pas avoir été pressé. De toute façon, je vois votre point de maintenant. J'étais confus parce que vous utilisez
self.startIndex
paramètre à initialiserstartIndex
etstartIndex
paramètre à initialiserendIndex
. Si vous utilisezself.startIndex
de vos limites, vous serez capable de l'utiliser justebounds.upperBound
pour la fin de l'indice de décalage. Il serait même préférable de choisir des noms différents à partir des variables de ChaînestartIndex
etendIndex
pour plus de clarté. Cela vous permettra aussi de supprimer tous lesself
références.Oh, je vois! Belle prise, Zmicier! J'ai édité la réponse.
OriginalL'auteur p-sun
Votre question (et d'auto-réponse) a 2 problèmes:
Subscripting une chaîne avec
Int
n'a jamais été disponible dans de Swift de la Bibliothèque Standard. Ce code est non valide aussi longtemps que Swift existe:La nouvelle
String.Index(encodedOffset: )
retourne un index en UTF-16 (16 bits) codage. Swift de la chaîne utilise Étendue de Graphème Cluster, ce qui peut prendre entre 8 et 64 bits pour stocker un caractère. Les émoticônes faire une très bonne démonstration:En fait, l'obtention de la
String.Index
n'a pas du tout changé dans Swift 4, pour le meilleur ou pour le pire:OriginalL'auteur Code Different
Cette erreur signifie que vous ne pouvez pas utiliser un Int dans l'indice de format – vous devez utiliser une Chaîne de caractères.De l'Index, vous pouvez initialiser avec un encodedOffset Int.
C'est sur GitHub dans la Norme Swift de la Bibliothèque de dépôt dans un fichier appelé UnavailableStringAPIs.swift.gyb dans le fond d'un classeur verrouillé coincé dans une ancienne lavabo avec un signe sur la porte disant: "Méfiez-vous de l'Leopard". lien
encodedOffset
ici; il ne correspond pas forcément aux personnages, il (actuellement) correspond à de code UTF-16 unités (qui vient de passe pour être des caractères pour les chaînes ASCII). Par exemple, aveclet myString = "hello"
,mySubstring
est juste(parce que c'est codé avec 2 de code UTF-16 unités). Avec
let myString = "hello"
, le subscripting soulève une erreur d'exécution, commeest codé avec 4 de code UTF-16 unités. Au lieu d'utiliser
encodedOffset:
, utilisezmyString.index(myString.startIndex, offsetBy: 2)
; ce qui parle en ce qui concerne les personnages.(notez également que
String
's allaient indice renvoieSubstring
, pasString
dans Swift 4)Que faire si je veux que ma limite inférieure d'être quelque chose de plus élevé que myString.startIndex? J'ai mis à jour l'exemple à ne pas commencer à 0. Je suppose que j'ai pu initialiser une Plage à l'aide de la fonction init(uncheckedBounds: (inférieure:supérieure:)) et de prendre ses limites inférieure et supérieure. J'ai mis à jour l'exemple en ce qui concerne la sous-Chaîne.
Pour obtenir un index à la position 1, vous pouvez dire
let lowerBound = myString.index(myString.startIndex, offsetBy: 1)
oulet lowerBound = myString.index(after: myString.startIndex)
.OriginalL'auteur Barry Jones