无法使用类型为“(Range )”的参数列表调用类型“Range ”的初始值设定项

时间:2023-01-23 22:05:35

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:

更新到Xcode 10 beta后,显然是随Swift 4.1.50一起提供的,我看到以下错误,我不知道如何修复:

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

无法使用类型为“(Range )”的参数列表调用类型“Range ”的初始值设定项

in the following function at Range<Index>(start..<self.endIndex) (line 3):

在Range 的以下函数中(start .. )(第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?

知道如何修复初始化程序吗?

2 个解决方案

#1


15  

Some background:

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

在Swift 3中,引入了额外的范围类型,总共有四种(参见例如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

通过在Swift 4.2中实现SE-0143条件一致性,“可数”变体不再是单独的类型,而是(约束的)类型别名,例如

 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.

struct Range的初始化程序。所有这些更改都是使用条件一致性(#13342)提交的[stdlib] [WIP]消除(已关闭)CountableRange的一部分。

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):

另一种选择是使用单侧范围(在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
    }
}

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

这是因为子串self [start ...]与原始字符串self共享其索引。

#2


3  

Turns out, ranges do not have to be initialized but can simply be created as follows:

事实证明,范围不必初始化,但可以简单地创建如下:

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

In this case, the code would be fixed by replacing Range<Index>(start..<self.endIndex) with:

在这种情况下,代码将通过将Range (start .. )替换为:

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

#1


15  

Some background:

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

在Swift 3中,引入了额外的范围类型,总共有四种(参见例如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

通过在Swift 4.2中实现SE-0143条件一致性,“可数”变体不再是单独的类型,而是(约束的)类型别名,例如

 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.

struct Range的初始化程序。所有这些更改都是使用条件一致性(#13342)提交的[stdlib] [WIP]消除(已关闭)CountableRange的一部分。

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):

另一种选择是使用单侧范围(在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
    }
}

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

这是因为子串self [start ...]与原始字符串self共享其索引。

#2


3  

Turns out, ranges do not have to be initialized but can simply be created as follows:

事实证明,范围不必初始化,但可以简单地创建如下:

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

In this case, the code would be fixed by replacing Range<Index>(start..<self.endIndex) with:

在这种情况下,代码将通过将Range (start .. )替换为:

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