2

Im learning swift currently. While learning I'm stuck with generics. Im solving one simple problem that -> return index of specified element in an array

import UIKit

extension Array
{

func indexOfLetter<T:Equatable>(item:T) -> Int
{
    var i = 0
    for (index, value) in enumerate(self)
    {
        if value == item
        {
            return i
        }
        i++
    }

    return -1;
}
}


var arrayOfItems = ["A","B"]
arrayOfItems.indexOfLetter("A")

in this code I'm getting error that we

Can not compare two operands using == operator which are of type T.

nhgrif
  • 61,578
  • 25
  • 134
  • 173
Rajesh
  • 546
  • 9
  • 29
  • It doesn't describe your problem, but you *could* eliminate `var i` and just `return index` which is currently needlessly unused... and the method would be better returning an `Int?` and passing back `nil` rather than `-1` when unfound. – nhgrif Jun 25 '15 at 12:14
  • 1
    It is the same problem as in the referenced question: You cannot write a method on a generic type that is more restrictive on the template. – In Swift 1.2, you would have to define a global function instead. In Swift 2, you can solve it with a protocol extension. – Martin R Jun 25 '15 at 12:31
  • I found the solution by unwrapping the objects. import UIKit extension Array { func indexOfLetter(item:U) -> Int { var i = 0 for (index, value) in enumerate(self) { if (value as! NSString) == (item as! NSString) { return i } i++ } return -1; } } var arrayOfItems:Array = ["A","B"] arrayOfItems.indexOfLetter("B") – Rajesh Jun 26 '15 at 06:57

1 Answers1

4

The answer to your problem becomes more clear if we use a letter other than T for our generic identifier.

Change the method signature to use the letter U. And now we get this error message:

enter image description here

Binary operator '==' cannot be applied to operands of type 'T' and 'U'

This is the same error, but it's made more clear by using a different letter. The Array type is already a generic whose generic identifier is T for its type.

When we use U it unmasks the real problem.

The Equatable protocol only requires that our type defines == for comparisons to itself. We could compare two U's as long as U's type is Equatable. But the Equatable protocol does not ensure that we can compare a U to a T using ==.

This Stack Overflow answer can provide some insight on the difficulties of using the Equatable protocol with generics.

Community
  • 1
  • 1
nhgrif
  • 61,578
  • 25
  • 134
  • 173