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
Swift distance() method throws fatal error: can not increment endIndex
提问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 range
had 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!.startIndex
points 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!.startIndex
never matches to the character boundaries, and the for
loop run out the string. That's why you see the exception.
正如您所看到的,range!.startIndex
从不匹配字符边界,for
循环用完字符串。这就是您看到异常的原因。
In theory, since String
is considered as "Collection of Character
s" in Swift, "?Д?"
should not be a substring of "hello#?Д?"
.
理论上,由于在 Swift 中String
被视为“ Character
s 的集合”, "?Д?"
因此不应是 "hello#?Д?"
.
I think .rangeOfString()
uses NSString
implementation 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。