Après la mise à jour vers la version bêta de Xcode 10, qui vient apparemment avec Swift 4.1.50, l'erreur suivante s'affiche, mais je ne sais pas comment la corriger:
Impossible d'appeler l'initialiseur pour le type 'Range <String.Index>' avec une liste d'arguments de type '(Range <String.Index>)'
dans la fonction suivante en Range<Index>(start..<self.endIndex)
(ligne 3):
func index(of aString: String, startingFrom position: Int? = 0) -> String.Index? {
let start: String.Index = self.index(self.startIndex, offsetBy: position!)
let range: Range<Index> = Range<Index>(start..<self.endIndex)
return self.range(of: aString, options: .literal, range: range, locale: nil)?.lowerBound
}
Une idée de comment réparer l'initialiseur?
Dans Swift 3, des types d’intervalle supplémentaires ont été introduits, soit un total de quatre (voir par exemple Ole Begemann: Intervalles dans Swift =):
Range, ClosedRange, CountableRange, CountableClosedRange
Avec l'implémentation de SE-0143 Conformités conditionnelles dans Swift 4.2, les variantes "dénombrables" ne sont plus des types séparés, mais des alias de types (sous contrainte), par exemple
public typealias CountableRange<Bound: Strideable> = Range<Bound>
where Bound.Stride : SignedInteger
en conséquence, diverses conversions entre les différents types de plage ont été supprimées, telles que la
init(_ other: Range<Range.Bound>)
initialiseur de struct Range
. Toutes ces modifications font partie du [stdlib] [WIP] Éliminer CountableRange (Closed) à l'aide de la conformité conditionnelle (# 13342) commit.
Donc c'est la raison pour laquelle
let range: Range<Index> = Range<Index>(start..<self.endIndex)
ne compile plus.
Comme vous l'avez déjà compris, ceci peut être simplement résolu comme
let range: Range<Index> = start..<self.endIndex
ou juste
let range = start..<self.endIndex
sans l'annotation de type.
Une autre option consiste à utiliser une plage unilatérale (introduite dans Swift 4 avec SE-0172 Un sur les côtés ):
extension String {
func index(of aString: String, startingFrom position: Int = 0) -> String.Index? {
let start = index(startIndex, offsetBy: position)
return self[start...].range(of: aString, options: .literal)?.lowerBound
}
}
Cela fonctionne car la sous-chaîne self[start...]
partage ses index avec la chaîne d'origine self
.
Il s'avère que les plages ne doivent pas être initialisées mais peuvent simplement être créées comme suit:
let range: Range<Index> = start...end
Dans ce cas, le code serait corrigé en remplaçant Range<Index>(start..<self.endIndex)
par:
let range: Range<Index> = start..<self.endIndex
J'ai eu le même problème, vous pouvez utiliser ce code pour résoudre le problème -
let range = startIndex .. <characters.index (startIndex, offsetBy: 1)
Référence: https://github.com/Ahmed-ALi/JSONExport/issues/121
J'ai migré de xcode 9.2 vers xcode 10.1 puis j'ai commencé à faire face à cette erreur et à le résoudre de cette manière
let range = start...end