swift - 无法为类型“范围”调用初始化程序' 带有类型为 '(Range)'
问题描述
更新到 Xcode 10 beta(显然是 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
}
知道如何修复初始化程序吗?
解决方案
一些背景:
在 Swift 3 中,引入了额外的范围类型,总共有四种(参见例如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 使用条件一致性 (#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
。