Невозможно вызвать инициализатор для типа "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..

Ссылка: https://github.com/Ahmed-Ali/JSONExport/issues/121

Я перешел с xcode 9.2 на xcode 10.1, а затем начал сталкиваться с этой ошибкой и разрешил таким образом

let range = start...end

Другие вопросы по тегам