tyeen tyeen - 1 year ago 64
Swift Question

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

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


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

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

Answer Source

range!.startIndex points here:


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

Therefore, This code:

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


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.

In theory, since String is considered as "Collection of Characters" in Swift, "゚Д゚" should not be a substring of "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.