27

どうやら Swift 4.1.50 に付属している Xcode 10 ベータ版に更新した後、修正方法がわからない次のエラーが表示されます。

タイプ '(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
}

イニシャライザを修正する方法はありますか?

4

4 に答える 4

58

背景:

Swift 3 では、追加の範囲タイプが導入され、合計 4 つになりました (たとえば、Ole Begemann: Ranges in Swift 3を参照してください)。

Range, ClosedRange, CountableRange, CountableClosedRange

Swift 4.2 でのSE-0143 条件付き準拠の実装により、「カウント可能な」バリアントはもはや別個の型ではなく、(制約付きの) 型エイリアスです。たとえば、

 public typealias CountableRange<Bound: Strideable> = Range<Bound>
      where Bound.Stride : SignedInteger

その結果、さまざまな範囲タイプ間のさまざまな変換が削除されました。

init(_ other: Range<Range.Bound>)

のイニシャライザstruct Range。これらすべての変更は、 [stdlib][WIP] Eliminate (Closed)CountableRange using conditional conformance (#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 One-sided Rangesで導入されました):

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

于 2018-06-06T11:49:00.590 に答える
6

結局のところ、範囲を初期化する必要はありませんが、次のように簡単に作成できます。

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

この場合、コードは次のものに置き換えることで修正されますRange<Index>(start..<self.endIndex)

let range: Range<Index> = start..<self.endIndex
于 2018-06-06T07:25:51.603 に答える