Невозможно вызвать инициализатор для типа "Range<String.Index>" со списком аргументов типа "(Range<String.Index>)"
После обновления до бета-версии Xcode 10, которая, по-видимому, поставляется с Swift 4.1.50, я вижу следующую ошибку, которую я не знаю, как исправить:
Невозможно вызвать инициализатор для типа "Range
" со списком аргументов типа "(Range )"
в следующей функции в Range<Index>(start..<self.endIndex)
(строка 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
}
Есть идеи как исправить инициализатор?
3 ответа
Немного предыстории:
В Swift 3 были введены дополнительные типы диапазонов, что в сумме составило четыре (см., Например, Ole Begemann: Диапазоны в Swift 3):
Range, ClosedRange, CountableRange, CountableClosedRange
С внедрением условных соответствий SE-0143 в Swift 4.2 "счетные" варианты больше не являются отдельными типами, а являются псевдонимами (ограниченными) типа, например
public typealias CountableRange<Bound: Strideable> = Range<Bound>
where Bound.Stride : SignedInteger
и, как следствие, были удалены различные преобразования между различными типами диапазонов, такие как
init(_ other: Range<Range.Bound>)
инициализатор struct Range
, Все эти изменения являются частью коммита [stdlib][WIP] Eliminate (Closed)CountableRange с использованием условия условного соответствия (#13342).
Так вот почему
let range: Range<Index> = Range<Index>(start..<self.endIndex)
больше не компилируется.
Как исправить
Как вы уже поняли, это можно просто исправить как
let range: Range<Index> = start..<self.endIndex
или просто
let range = start..<self.endIndex
без аннотации типа.
Другой вариант - использовать односторонний диапазон (представлен в Swift 4 с односторонними диапазонами 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
}
}
Это работает, потому что подстрока self[start...]
делится своими индексами с исходной строкой self
,
Оказывается, диапазоны не нужно инициализировать, а можно просто создать следующим образом:
let range: Range<Index> = start...end
В этом случае код будет исправлен путем замены Range<Index>(start..<self.endIndex)
с:
let range: Range<Index> = start..<self.endIndex
У меня была та же проблема, вы можете использовать этот код для решения проблемы -
let range = startIndex..
Я перешел с xcode 9.2 на xcode 10.1, а затем начал сталкиваться с этой ошибкой и разрешил таким образом
let range = start...end