In our process App When developing , A common operation is to determine whether two objects are equal . For example, whether two strings are equal . The so-called equal It has two meanings . One is that the values are equal , There is also a reference to equality . If you are familiar with Objective-C To develop it , You know that Objective-C Provides us with a series of `isEqual:` Method to determine whether the values are equal , and == The equal sign is used to determine whether references are equal . Let's take a look at one Objective-C You'll see more clearly from the example of ：

``````NSArray *arr1 = @[@"cat",@"hat",@"app"];
NSArray *arr2 = @[@"cat",@"hat",@"app"];
NSLog(@"result %i", (arr1 == arr2)); // result 0
NSLog(@"result %i", [arr1 isEqualToArray:arr2]); // result 1
``````

In the above code , We define two arrays ,arr1 and arr2 These two arrays hold the same elements . Next we compare them equally and output the result . For the first time, we used == Compare with the equal sign , The result is 0, That is to say, the comparison failed . I believe that students with some experience should understand , Because stay Objective-C in == The comparison is to quote , because arr1 and arr2 It's two different objects , So even if their values are the same , But their citations are also different . therefore == Comparison will fail . And the second comparison is NSArray Of isEqualToArray Method , This method is used for value comparison , Because the values of the two arrays are the same , therefore isEqualToArray The comparison method returns 1.

<!-- more -->

### Equatable agreement

We go through Objective-C I understand equal The operation mechanism of operation , Contains value equality and reference equality . Now let's go back to Swift In the to . Believe there is Objective-C Experienced students will be looking for isEqual Method , But you will find Swift None of the native classes of isEqual The definition of .

If you want to isEqual Get to know more about , This article Equality It has a detailed explanation . Let's just talk about it here .

Swift There is no iEqual Method definition , But in a more natural way , Overload operators To deal with it equal Judgmental . heavy load `==` The operator is through Equatable Agreement to complete . We implement the methods in this protocol to overload operators .

``````func ==(lhs: Self, rhs: Self) -> Bool
``````

Swift Implementation of the array class , be called `Array`, About `Array` type , This article has a detailed description Swift Tips - Array type .Swift Medium `Array` Type implements `Equatable` agreement , So we can `Array` Examples of types are provided through `==` Operators for comparison ：

``````var arr1 = ["cat","hat","app"]
var arr2 = ["cat","hat","app"]
println arr1 == arr2 // true
``````

We see , stay Swift You can use `==` Compare the effect and Objective-C Medium `isEqual:` The actual effect of the method is the same . They all compare values .Swift This point of characteristic and Objective-C It's a little different .Swift In the native class of , It's almost done `Equatable` agreement .

#### Realization Equatable agreement

We now understand Swift Medium `Equatable` agreement . I believe careful students have found out , We are Swift The reason why we can use `==` Compare , Because the object of this symbolic operation implements `Equatable` agreement . If you use it for objects that don't implement this protocol `==` For comparison ？ We can take a look at this code ：

In the above code , We define a `Name` class , And instantiate two objects of this class `john` and `copy`. And then we use `==` Compare the two , At this point, the compiler reported an error . The reason is that our class doesn't implement `Equatable` agreement .

Now let's modify this class ：

``````class Name :Equatable {
var firstName:String?
var lastName:String?
init(firstName first:String, lastName last:String){
self.firstName = first
self.lastName = last
}
}
func ==(lhs: Name, rhs: Name) -> Bool {
return lhs.firstName == rhs.firstName && lhs.lastName == rhs.lastName
}
``````

In our revision , We did `Equatable` agreement , And implemented `func ==(lhs: Name, rhs: Name) -> Bool` Method . The only way to judge is `firstName` and `lastName` If they are all equal , these two items. Name Objects are equal .

After making this change , We can continue to use our previous judgment ：

``````if john == copy {
print("equal") //equal
}
``````

This time, ,`if` Statement `print` The method was successfully implemented .

Now we know Swift Most classes in have their own pairs of `==` The implementation of the operator . So what if we want to compare whether the references of two objects are equal ？

We can use `ObjectIdentifier` Class to get the reference ID of the object , We explicitly call the constructor of this class to get the object reference , And compare ：

``````if ObjectIdentifier(john) == ObjectIdentifier(copy) {
print("equal")
}else{
print("not equal") // not equal
}
``````

We use it `ObjectIdentifier` Got the reference address of the object , also `ObjectIdentifier` It's realized itself `Equatable` agreement , therefore We're interested in the converted `ObjectIdentifier` Object use `==` Compare , You can tell if the application is the same .

### Comparable

We just introduced `Equatable` agreement , And there's another one related to it `Comparable` agreement . `Equatable` The protocol is to compare equality . and `Comparable` It's a comparison of the order . such as Swift Medium `Double` class , And that's what happened `Comparable` agreement ：

``````var left:Double = 30.23
var right:Double = 50.55
if left < right {
print("30.23 is less than 50.55")
}
``````

Realized `Comparable` Protocol class , You can use `>,<,<=,>=` These operators compare . The definition of this agreement is as follows ：

``````protocol Comparable { ... }
func <=(lhs: Self, rhs: Self) -> Bool
func >=(lhs: Self, rhs: Self) -> Bool
func >(lhs: Self, rhs: Self) -> Bool
``````

Do you think , To implement the comparison operation , We need to realize all the methods in this . Let's take a few minutes to take a closer look at the definition of this Agreement , And think about it .

1. First , There are four operators for order comparison ,`<=`,`>=`,`>`,< You can take a look at this agreement , It seems that it's missing < What about the definition of ？
2. then , Let's analyze the logic of these operators ,`>=`, It's actually `>` and `==` A juxtaposition of , If we implement these two operators , actually `>=` The logic of this is clear . This `>=` The logic of the operator is usually this statement ： `return lhs > rhs || lhs == rhs`.

Through the above brief analysis , Did we find a rule ？ In fact, that is , We just need to implement some operators , You can deduce the logic of other operators . for instance , On the surface of the above `Comparable` From the definition of interface ,`<=` and `>` These two operators , We only need to implement one of them to derive the other . such as , We did `>` The operator , that '<=' The operator only needs to negate the previous function .

that , We `<=` Implementation of function , Just do something like this ：

``````func <=(lhs: Self, rhs: Self) -> Bool {
return !(lhs > rhs)
}
``````

Think about it , In fact, we just need to achieve `==` and `<` The operator , Several other operators can be derived from these two ：

1. >= Can pass `<` The logic of negation and `==` A logic or operation derived together .
2. > Can pass `<` We can deduce from the logic of .
3. <= Can pass `<` and `==` The logic or operation of .

About this knowledge , There is a concept called Strictly total order , Students who are interested can read .

Now the problem is again , We just need to achieve `==` and `<` Method logic can complete the comparison operation , So the implementation code for other operators , It's all the same . It's redundant .

and Swift It's solving this problem for us , Provides us with the default implementation of the protocol , go through Swift Document , We'll find that in addition to `Comparable` agreement , I've also defined one `_Comparable` agreement , The former is inherited from the latter . `_Comparable` The definition of the agreement is as follows ：

``````protocol _Comparable { ... }
func <(lhs: Self, rhs: Self) -> Bool
``````

We found that , What we just lost `<` I found... Here . `_Comparable` Namely Swift An example of the default protocol implementation mechanism provided in .`_Comparable` Several other operators are provided in the protocol `>=,>,<=` Default implementation of .

because `Comparable` Simultaneous inheritance from `_Comparable` and `Equatable` agreement , So we just need to achieve `<` and `==` These two operators , Can complete the implementation of the whole comparison operation . Let's take an example ：

``````class Name: Comparable {
var firstName:String
var lastName:String
init(firstName first:String,lastName last:String){
self.firstName = first
self.lastName = last
}
}
func ==(lhs: Name, rhs: Name) -> Bool {
return lhs.firstName == rhs.firstName && lhs.lastName == rhs.lastName
}
func <(lhs: Name, rhs: Name) -> Bool {
return lhs.firstName < rhs.firstName && lhs.lastName < rhs.lastName
}
let john = Name(firstName: "John", lastName: "Smith")
let johnClone = Name(firstName: "John", lastName: "Smith")
let jack = Name(firstName: "Jack", lastName: "Smith")
let mary = Name(firstName: "Mary", lastName: "Williams")
print(john >= jack) //true
print(john <= jack) //true
print(john == jack) //false
print(john > jack) //false
print(john < jack) //false
print(jack < mary) //true
print(john == johnClone) //true
var names:Array<Name> = [johnClone,mary,john,jack]
//[{firstName "John" lastName "Smith"}, {firstName "Mary" lastName "Williams"}, {firstName "John" lastName "Smith"}, {firstName "Jack" lastName "Smith"}]
names.sort { (lhs, rhs) -> Bool in
return lhs > rhs
}
//[{firstName "Mary" lastName "Williams"}, {firstName "John" lastName "Smith"}, {firstName "John" lastName "Smith"}, {firstName "Jack" lastName "Smith"}]
``````

We're here to complete `Comparable` agreement , We define a `Name` class , And implemented `<` and `==` Protocol method , One of them is from `_Comparable` agreement , One from `Equatable` agreement . and `Comparable` Three comparison methods in the protocol , Already in `_Comparable` The default implementation is provided in , So we don't have to do it ourselves again .（ Pay attention to two Comparable and _Comparable The difference between underscores , These are two different agreements .）

### Hashable

The last thing to mention is Hashable agreement . We are right. Dictionary It should be no stranger to the concept of , So if an object wants to be Dictionary Of key Words , Then we need to achieve Hashable agreement .

Swift The following classes are implemented by default Hashable agreement ：

• Double
• Float, Float80
• Int, Int8, Int16, Int32, Int64
• UInt, UInt8, UInt16, UInt32, UInt64
• String
• UnicodeScalar
• ObjectIdentifier

So instances of these classes , It can be used as Dictionary Of key. Let's take a look Hashable Definition of agreement ：

``````protocol Hashable { ... }
var hashValue: Int { get }
``````

The definition is very simple , We just need to achieve `hashValue` Definition hash The calculation method of the value is just . About hash The optimization method of value is another topic , So we'll just have a brief discussion here , Will use the hash Value again XOR operation to calculate the new hash value . Or our Name Class, for example ：

``````
class Name: Comparable,Hashable {
...
var hashValue: Int {
return self.firstName.hashValue ^ self.lastName.hashValue
}
}
``````

Next we'll use it as a dictionary key 了 ：

``````let john = Name(firstName: "John", lastName: "Smith")
let johnClone = Name(firstName: "John", lastName: "Smith")
let jack = Name(firstName: "Jack", lastName: "Smith")
let mary = Name(firstName: "Mary", lastName: "Williams")
var nameMap:[Name: String] = [:]
nameMap[john] = "Manager"
nameMap[jack] = "Stuff"
``````

This article introduces Swift Three agreements in `Equatable`,`Comparable`,`Hashable`, Although we usually don't pay much attention to these agreements , But in our development work , They don't work all the time , our if sentence , The sorting operation , Dictionary and array operations , It's all about these agreements . and Swift Most of the categories in , Basically, these agreements have been realized . It can be said that although we often forget them , But they are around us all the time . After getting to know them , It will help us a lot .

For more articles, please visit : www.theswiftworld.com

More good articles , Scan code concerns WeChat official account ：

-->

## Swift Explore - About Swift Medium isEqual A little bit of exploration of more related articles

1. iOS Development --Swift How to complete the project Swift and OC The hybrid bridge of (Cocoapods The same applies )

because SDK Most of them are now OC edition , So if you're a major Swift Language developers , We have to face the problem of how to let OC and Swift Compatible in a project , If you haven't done this before , I'll feel like I'm at a loss , Never mind ...

2. Used in the same project Swift and Objective-C(Swift 2.0 to update )-b

This section contains : Mix and Match summary (Mix and Match Overview) In the same application target Import (Importing Code from Within the Sa ...

3. Swift Interoperability ： Use Objective-C Feature writing Swift class （Swift 2.0 edition ）-b

This section includes : Inherit Objective-C Class (Inheriting from Objective-C Classes) Adopt protocols (Adopting Protocols) Write constructors and destructors (Writ ...

4. iOS Swift Module exercises /swift Based on learning

SWIFT Project exercise      SWIFT Project exercise 2 iOS Swift Basic knowledge code recommend :Swift Learn to use knowledge code software 0.swift Macro definition in ( Use methods instead of macros ) One . View  + Control 1.UIImag ...

5. [Swift A] - Using Swift with Cocoa and Objective-C--Mix and Match

Swift And Objective-C Compatibility allows you to use both languages in the same project . You can call this “mix and match” To develop applications based on mixed language . Use Swfit The latest features of --“mix a ...

6. Object storage - Swift principle And Swift+keystone+dashboard Architecture building

1. Principle introduction Swift framework . Principle and function : http://www.cnblogs.com/sammyliu/p/4955241.html The summary is very detailed and comprehensive , Benefited greatly , Thanks for sharing. . 2. keys ...

7. swift.org - About Swift Official website notes

About Swifthtml, body {overflow-x: initial !important;}html { font-size: 14px; } body { margin: 0px; ...

8. C# A little bit of the harvest of precise timing in 【 turn 】

C# A little bit of the harvest of precise timing in [ turn ] All of the following code runs in the environment :Windows 2003, Intel(R) Core(TM) 2 Duo CPU E8400 @  3.00GHz 2.99GHz,2.96G ...

9. C++ in extern “C” Deep exploration of meaning

C++ in extern “C” Deep exploration of meaning extern “C” Is a two-way need to use the syntax , That is to say cpp quote c The header file , perhaps c quote cpp You need to use it when you write a file . but extern “C” Always only in cpp lead ...

## Random recommendation

1. python in str（） and repr（） The difference between

>>> s = 'Hello, world.' >>> str(s) 'Hello, world.' >>> repr(s) "'Hel ...

2. bzoj3272 3638

Good question , In this problem, we can use line segment tree to quickly simulate the cost flow and find the longest augmented path It's obvious how to do this type node=record s,lx,rx,mx,lp,rp,pb,pe:longint; end; ..*,. ...

3. Java Threads ： What is thread

One Basic concepts multitasking : The ability to run multiple programs at the same time . Each task is called a thread . A program that can run more than one thread at the same time is called a multithreaded program . Java The programs are all running in Java virtual machine (JVM) in , stay JVM Internal , There are many programs ...

4. from &quot; Hanoi &quot; Classic recursion to JS Recursive function

Preface Reference resources <JavaScript The essence of language > Recursion is a powerful programming technique , He decomposed a problem into a set of similar subproblems , Every problem is solved by a common solution . A recursive function is a function that calls itself directly or indirectly , Generally come ...

5. CCF-201604-1- Break point count

Problem description Question number : 201604-1 The title of the test question : Break point count The time limit : 1.0s Memory limit : 256.0MB Problem description : Problem description Given n An integer represents a store in succession n Days of sales . If sales were up one day ...

6. tomcat Virtual directory

stay webapps At the same directory Next build a webapps_abc The catalog of , Put the site root abc Folder in webapps_abc Under the table of contents : find conf In the catalog ,server.xml file , stay service Add under node ...

7. A Chinese character to Pinyin php class

The code comes from the Internet , You can use <?php function Pinyin(\$_String, \$_Code='gb2312') { \$_DataKey = "a|ai|an|ang|ao|ba| ...

8. division &amp; Peishu theorem

2018-03-11 17:39:22 One . division In mathematics , division , Also known as Euclid algorithm ( English :Euclidean algorithm), It's an algorithm for finding the greatest common divisor . Rolling phase division first appeared in Euclid &l ...

9. codeforces 453C Little Pony and Summer Sun Celebration

codeforces 453C Little Pony and Summer Sun Celebration This question is very interesting , Although there are a lot of online answers , But I still want to archive my understanding . The meaning of the title can be changed in this way : initial ...

10. HDU2189 Let's go together in the next life

I haven't blogged for a long time , Recently, I encountered the following wonderful mistakes , I don't quite get it, but I think you are really terrific , I can't help sending an article /* The generating function , Because prime numbers are required , So let's start with a prime table , All the factors are prime numbers But there's a wonderful thing , When num Initial value 1, And it doesn't come out , It's been running for a long time ...