xcode Swift distance() 方法抛出致命错误:不能增加 endIndex

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27191865/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 06:16:43  来源:igfitidea点击:

Swift distance() method throws fatal error: can not increment endIndex

xcodeswift

提问by tyeen

I was trying to find a substring match in a string, and get the matched position.

我试图在字符串中找到一个子字符串匹配,并获得匹配的位置。

I can't figure out what's wrong with the following code:

我无法弄清楚以下代码有什么问题:

let str1 = "hello#?Д?"
let cmp = "?Д?"
let searchRange = Range(start: str1.startIndex, end: str1.endIndex)
let range = str1.rangeOfString(cmp, options: .allZeros, range: searchRange)

println("\(searchRange), \(range!)") // output: 0..<9, 6..<9

let dis = distance(searchRange.startIndex, range!.startIndex) // fatal error: can not increment endIndex! reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
// let dis = distance(searchRange.startIndex, range!.endIndex) // This will go and output: distance=7

println("distance=\(dis)")

As the comments suggested, although the rangehad valid values, the distance() method threw a fatal error.

正如评论所暗示的那样,尽管range具有有效值,但 distance() 方法抛出了致命错误。

If I'm wrong about the use of distance(), what method should I use to archive the target? Any advice would be helpful. Thanks.

如果我对 distance() 的使用有误,我应该使用什么方法来存档目标?任何意见将是有益的。谢谢。

采纳答案by rintaro

range!.startIndexpoints here:

range!.startIndex点这里:

"hello#?Д?"
       ^

But, in this case, #?is a single character in Swift.

但是,在这种情况下,#?是 Swift 中的单个字符。

Therefore, This code:

因此,此代码:

for var idx = searchRange.startIndex; idx != range!.startIndex; idx = idx.successor() {
    println("\(idx): \(str1[idx])");
}

prints:

印刷:

0: h
1: e
2: l
3: l
4: o
5: #?
7: Д?
fatal error: Can't form a Character from an empty String
// and emits BAD_INSTRUCTION exception

As you can see range!.startIndexnever matches to the character boundaries, and the forloop run out the string. That's why you see the exception.

正如您所看到的,range!.startIndex从不匹配字符边界,for循环用完字符串。这就是您看到异常的原因。

In theory, since Stringis considered as "Collection of Characters" in Swift, "?Д?"should not be a substring of "hello#?Д?".

理论上,由于在 Swift 中String被视为“ Characters 的集合”, "?Д?"因此不应是 "hello#?Д?".

I think .rangeOfString()uses NSStringimplementation which treats string as a sequence of unichar. I don't know this should be considered as a bug or not.

我认为.rangeOfString()使用NSString将字符串视为unichar. 我不知道这是否应该被视为错误。

回答by Daniel T.

Try this:

尝试这个:

func search<C: CollectionType where C.Generator.Element: Equatable>(col1: C, col2: C) -> C.Index? {
    if col2.startIndex == col2.endIndex {
        return col1.startIndex
    }

    var col1Ind = col1.startIndex
    while col1Ind != col1.endIndex {
        var ind1 = col1Ind
        var ind2 = col2.startIndex
        while col1[ind1] == col2[ind2] {
            ++ind1; ++ind2
            if ind2 == col2.endIndex { return col1Ind }
            if ind1 == col1.endIndex { return nil }
        }
        ++col1Ind
    }
    return nil
}

Searches for the first instance of the col2 sequence in col1. If found, returns the index of the start of the sub-sequence. If not found, returns nil. If col2 is empty, returns the startIndex of col1.

在 col1 中搜索 col2 序列的第一个实例。如果找到,则返回子序列开始的索引。如果未找到,则返回 nil。如果 col2 为空,则返回 col1 的 startIndex。