Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different behavior of index(after:) in Collection and String

Tags:

swift

I'm curious, why this code works without any kind of error:

let a = [1]
print(a.index(after: a.endIndex)) // 2

But if we try to repeat this code with String type, we get an error:

let s = "a"
print(s.index(after: s.endIndex)) // Fatal error: Can't advance past endIndex

According to Collection and String docs, they all have same statement:

A valid index of the collection. i must be less than endIndex.

Is it a bug or all works as it should? I'm using swift 4.2.

like image 252
pacification Avatar asked Mar 12 '19 18:03

pacification


People also ask

What is an index in Java?

Java String indexOf() Method The indexOf() method returns the position of the first occurrence of specified character(s) in a string. Tip: Use the lastIndexOf method to return the position of the last occurrence of specified character(s) in a string.

Is string a collection in Swift?

A string is a series of characters, such as "Swift" , that forms a collection. Strings in Swift are Unicode correct and locale insensitive, and are designed to be efficient.

How do you create an array of strings in Swift?

Swift makes it easy to create arrays in your code using an array literal: simply surround a comma-separated list of values with square brackets. Without any other information, Swift creates an array that includes the specified values, automatically inferring the array's Element type.


1 Answers

If we go to the source code of Array, we can find:

public func index(after i: Int) -> Int {
    // NOTE: this is a manual specialization of index movement for a Strideable
    // index that is required for Array performance.  The optimizer is not
    // capable of creating partial specializations yet.
    // NOTE: Range checks are not performed here, because it is done later by
    // the subscript function.
    return i + 1
}

In this case, we can rewrite code like this and finally get the crash:

let a = [1]
let index = a.index(after: a.endIndex)
print(a[index])

So, all works "as expected" for Array type, but we must check the result index by yourself, if we don't want to get crash at runtime

P.S. Useful link by @MartinR: https://forums.swift.org/t/behaviour-of-collection-index-limitedby/19083/3

like image 165
pacification Avatar answered Nov 15 '22 05:11

pacification