Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
609 views
in Technique[技术] by (71.8m points)

swift - Cannot invoke initializer for type 'Range<String.Index>' with an argument list of type '(Range<String.Index>)'

After updating to Xcode 10 beta, which apparently comes with Swift 4.1.50, I'm seeing the following error which I'm not sure how to fix:

Cannot invoke initializer for type 'Range< String.Index>' with an argument list of type '(Range< String.Index>)'

in the following function at Range<Index>(start..<self.endIndex) (line 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
}

Any idea how to fix the initializer?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Some background:

In Swift 3, additional range types were introduced, making a total of four (see for example Ole Begemann: Ranges in Swift 3):

Range, ClosedRange, CountableRange, CountableClosedRange

With the implementation of SE-0143 Conditional conformances in Swift 4.2, the “countable” variants are not separate types anymore, but (constrained) type aliases, for example

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

and, as a consequence, various conversions between the different range types have been removed, such as the

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

initializer of struct Range. All theses changes are part of the [stdlib][WIP] Eliminate (Closed)CountableRange using conditional conformance (#13342) commit.

So that is the reason why

let range: Range<Index> = Range<Index>(start..<self.endIndex)

does not compile anymore.

How to fix

As you already figured out, this can be simply fixed as

let range: Range<Index> = start..<self.endIndex

or just

let range = start..<self.endIndex

without the type annotation.

Another option is to use a one sided range (introduced in Swift 4 with 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
    }
}

This works because the substring self[start...] shares its indices with the originating string self.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...