swift - funciones - No se puede invocar el inicializador para el tipo ''Range<String.Index>'' con una lista de argumentos de tipo ''(Range<String.Index>)''
substring swift 4 (3)
Algunos antecedentes:
En Swift 3, se introdujeron tipos de rango adicionales, lo que hace un total de cuatro (ver, por ejemplo, Ole Begemann: Ranges en Swift 3 ):
Range, ClosedRange, CountableRange, CountableClosedRange
Con la implementación de las conformaciones condicionales SE-0143 en Swift 4.2, las variantes "contables" ya no son tipos separados, sino alias de tipo (restringidos), por ejemplo
public typealias CountableRange<Bound: Strideable> = Range<Bound>
where Bound.Stride : SignedInteger
y, como consecuencia, se han eliminado varias conversiones entre los diferentes tipos de rango, como el
init(_ other: Range<Range.Bound>)
Inicializador de la struct Range
de struct Range
. Todos estos cambios forman parte de [stdlib] [WIP] Eliminate (Closed) CountableRange mediante el uso de la confirmación condicional (# 13342) .
Así que esa es la razón por la cual
let range: Range<Index> = Range<Index>(start..<self.endIndex)
Ya no se compila.
Como arreglar
Como ya se ha dado cuenta, esto se puede arreglar simplemente como
let range: Range<Index> = start..<self.endIndex
o solo
let range = start..<self.endIndex
sin la anotación de tipo.
Otra opción es usar un rango de un solo lado (introducido en Swift 4 con rangos de un solo lado SE-0172 ):
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
}
}
Esto funciona porque la subcadena self[start...]
comparte sus índices con la cadena originadora self
.
Después de actualizar a Xcode 10 beta, que aparentemente viene con Swift 4.1.50, veo el siguiente error que no estoy seguro de cómo solucionar:
No se puede invocar el inicializador para el tipo ''Range <String.Index>'' con una lista de argumentos de tipo ''(Range <String.Index>)''
en la siguiente función en Range<Index>(start..<self.endIndex)
(línea 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
}
¿Alguna idea de cómo arreglar el inicializador?
Resulta que los rangos no tienen que inicializarse, sino que se pueden crear de la siguiente manera:
let range: Range<Index> = start...end
En este caso, el código se arreglaría reemplazando Range<Index>(start..<self.endIndex)
con:
let range: Range<Index> = start..<self.endIndex
Tuve el mismo problema. Puedes usar este código para solucionar el problema.
let range = startIndex .. <characters.index (startIndex, offsetBy: 1)
Referencia: https://github.com/Ahmed-Ali/JSONExport/issues/121