Generic type with custom Swift object

I wonder if there is a way to compare two instances of a typical type with the == operator in the following general 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? } 
+6
source share
3 answers

From Apple Developer Resources

Not every type in Swift can be compared with an equal operator (==). For example, if you create your own class or structure to represent a complex data model, then the equal value for this class or structure is not what 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 a corresponding error is reported when trying to compile the code.

However, all is not lost. The Swift standard library defines a protocol called Equatable, which requires any appropriate type to implement equal to the operator (==) and not equal to the operator (! =) To compare any two values โ€‹โ€‹of this type. All Standard Swifts types automatically support the Equatable protocol.

Any type that is Equatable can be safely used with the findIndex function, as it is guaranteed to be maintained equal to the operator. To express this fact, you write an Equatable type constraint as part of the definition of type parameters when defining a 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 an example 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 } 
+9
source

You can create your own implementation of the equivalence operators == and! =, for example:

 @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 
+2
source

To use the general compare() method, you need to make the class compatible with the Equatable protocol , and then you can use the == operator (however, you can just as easily call the == operator):

 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") } 
+1
source

Source: https://habr.com/ru/post/970248/


All Articles