Невозможно вызвать инициализатор для типа 'Range ‹String.Index›' со списком аргументов типа '(Range ‹String.Index›)'

После обновления до бета-версии Xcode 10, которая, по-видимому, поставляется с Swift 4.1.50, я вижу следующую ошибку, которую я не знаю, как исправить:

Невозможно вызвать инициализатор для типа 'Range ‹String.Index>' со списком аргументов типа '(Range‹ String.Index>)'

в следующей функции в 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
}

Есть идеи, как исправить инициализатор?


person LinusGeffarth    schedule 06.06.2018    source источник


Ответы (4)


Немного предыстории:

В Swift 3 были введены дополнительные типы диапазонов, всего четыре (см., Например, Оле Бегеманн: Диапазоны в 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.

person Martin R    schedule 06.06.2018
comment
ваша индексная функция не компилируется - person user3561494; 04.07.2019
comment
@ user3561494: Он компилируется для меня. Какую версию Xcode вы используете? Какое точное сообщение об ошибке? - person Martin R; 04.07.2019

Оказывается, диапазоны не нужно инициализировать, их можно просто создать следующим образом:

let range: Range<Index> = start...end

В этом случае код будет исправлен заменой Range<Index>(start..<self.endIndex) на:

let range: Range<Index> = start..<self.endIndex
person LinusGeffarth    schedule 06.06.2018

У меня была такая же проблема, вы можете использовать этот код, чтобы исправить проблему -

let range = startIndex .. ‹characters.index (startIndex, offsetBy: 1)

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

person Sushmita Sinha    schedule 09.10.2018

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

let range = start...end

person Awais Nasir    schedule 28.03.2019