一些背景:
在 Swift 3 中,引入了额外的范围类型,使总共
四个(例如,参见Ole Begemann:Swift 3 中的范围 https://oleb.net/blog/2016/09/swift-3-ranges/):
Range, ClosedRange, CountableRange, CountableClosedRange
随着实施SE-0143 有条件的一致性 https://github.com/apple/swift-evolution/blob/master/proposals/0143-conditional-conformances.md在 Swift 4.2 中,“可数”变体
例如,不再是单独的类型,而是(受约束的)类型别名
public typealias CountableRange<Bound: Strideable> = Range<Bound>
where Bound.Stride : SignedInteger
因此,不同类型之间的各种转换
范围类型已被删除,例如
init(_ other: Range<Range.Bound>)
的初始化器struct Range
。所有这些变化都是[stdlib][WIP] 使用条件一致性消除 (Closed)CountableRange (#13342) https://github.com/apple/swift/commit/9ee856f386f9be65234e25038a91a34fa07acacd commit.
所以这就是原因
let range: Range<Index> = Range<Index>(start..<self.endIndex)
不再编译。
怎么修
正如您已经想到的,这可以简单地修复为
let range: Range<Index> = start..<self.endIndex
or just
let range = start..<self.endIndex
没有类型注释。
另一种选择是使用一侧范围(在 Swift 4 中引入SE-0172 单边范围 https://github.com/apple/swift-evolution/blob/master/proposals/0172-one-sided-ranges.md):
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
.