titaniumdecoy
titaniumdecoy

Reputation: 19251

Why do I get an error when attempting to invoke indexOf on a generic ArraySlice?

The following function finds the second index of a given item in Array of Int:

func secondIndexOf(item: Int, inArray array: Array<Int>) -> Int? {
    if let firstIndex: Int = array.indexOf(item) {
        let slice: ArraySlice<Int> = array.suffixFrom(firstIndex + 1)
        return slice.indexOf(item)
    }
    return nil
}

However, when I attempt to create a generic version of this function to find the second Equatable item, I get an error:

func secondIndexOf<T: Equatable>(item: T, inArray array: Array<T>) -> T? {
    if let firstIndex: Int = array.indexOf(item) {
        let slice: ArraySlice<T> = array.suffixFrom(firstIndex + 1)
        return slice.indexOf(item) // Cannot invoke 'indexOf' with an argument list of type '(T)'
    }
    return nil
}

Why is this not valid Swift code, and what is the expected argument list if not (T)? Xcode autocomplete shows indexOf(element: Comparable) with which T should be compatible.

Upvotes: 2

Views: 387

Answers (1)

Nate Cook
Nate Cook

Reputation: 93276

The compiler is giving you a confusing error message here—it isn't actually concerned about the argument. The return value is the source of the problem, since you aren't returning a value of type T, but an index of the array. You just need to change your return type to Int?:

func secondIndexOf<T: Equatable>(item: T, inArray array: Array<T>) -> Int? {
    if let firstIndex: Int = array.indexOf(item) {
        let slice: ArraySlice<T> = array.suffixFrom(firstIndex + 1)
        return slice.indexOf(item)
    }
    return nil
}

Upvotes: 1

Related Questions