6

I wonder is there any way to compare two generic type instances with == operator in following generic function:

 func compare<T>(T a, T b) -> Bool {
    if a == b{
       // do something
       return true; 
    }else{
       // do another thing
       return false;
    }   
 }

Here is my custom object:

class MyObj{
  var id = 3
  var name: String?
}

3 Answers 3

10

From Apple Developer Resources,

Not every type in Swift can be compared with the equal to operator (==). If you create your own class or structure to represent a complex data model, for example, then the meaning of “equal to” for that class or structure is not something that Swift can guess for you. Because of this, it is not possible to guarantee that this code will work for every possible type T, and an appropriate error is reported when you try to compile the code.

All is not lost, however. The Swift standard library defines a protocol called
Equatable, which requires any conforming type to implement the equal to operator (==) and the not equal to operator (!=) to compare any two values of that type. All of Swift’s standard types automatically support the Equatable protocol.

Any type that is Equatable can be used safely with the findIndex function, because it is guaranteed to support the equal to operator. To express this fact, you write a type constraint of Equatable as part of the type parameter’s definition when you define the function:

func findIndex<T: Equatable>(array: T[], valueToFind: T) -> Int? {
    for (index, value) in enumerate(array) {
        if value == valueToFind {
            return index
        }
    }
    return nil
}

Here is a sample from their documentation explaining how to override ==

struct MyStruct: Equatable {
    var name = "Untitled"
}
func == (lhs: MyStruct, rhs: MyStruct) -> Bool {
    return lhs.name == rhs.name
}

let value1 = MyStruct()
var value2 = MyStruct()
let firstCheck = value1 == value2
// firstCheck is true

value2.name = "A New Name"
let secondCheck = value1 == value2
// secondCheck is false

In your case you would do,

class MyObj{
  var id = 3
  var name: String?
}

func == (lhs: MyObj, rhs: MyObj) -> Bool {
    return lhs.id == rhs.id
}
Sign up to request clarification or add additional context in comments.

1 Comment

So I have to implement Equatable protocol for my own object to make it comparable?
2

You can create your own implementation of the equivalence operators == and !=, like this:

@infix func == (left: MyObj, right: MyObj) -> Bool {
    return (left.id == right.id) && (left.name == right.name)
}
@infix func != (left: MyObj, right: MyObj) -> Bool {
    return !(left == right)
}

var obj1 = MyObj()
var obj2 = MyObj()
obj1.id = 5
obj1 == obj2 // false
obj2.id = 5
obj1 == obj2 // true

obj1.name = "John"
obj1 == obj2 // false

Comments

1

In order to use your generic compare() method, you need to make the class conform to the Equatable protocol and you can then use the == operator (however you could just as easily call the == operator directly):

import Cocoa

class MyObj : Equatable {
    var id: Int = 0
    var name: String?
}

func == (lhs: MyObj, rhs: MyObj) -> Bool {
    return lhs.id == rhs.id && lhs.name? == rhs.name?
}


func compare<T: Equatable>(a: T, b: T) -> Bool {
    return a == b
}

var obj1 = MyObj()
obj1.id = 12;
obj1.name = "Andy"
var obj2 = MyObj()
obj2.id = 12;
obj2.name = "Andy"

if compare(obj1, obj2) {
    println("equal")
} else {
    println("not equal")
}

4 Comments

Why did you use compare method? Can't you just compare using == operator?
@GokhanArik Yeah I mention that in my answer. Looking at the OP's question, however, he wants to do something within compare() itself.
Sorry I didn't pay attention to that.
Why is the == override function is outside of the class? If I have more than one equatable class, will it still work?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.