Swift Explore-A little exploration of the isequal in Swift

Source: Internet
Author: User
Tags comparable hashable

One of the things we often use when we do APP development is to determine if two objects are equal. For example, if two strings are equal. And the so-called equivalence has two meanings. One is the value is equal, and the other is the reference equality. If you are familiar with objective-c development, you will know that OBJECTIVE-C provides us with a series of isEqual: methods to judge the value equality, and the = = equals number is used to judge the reference equality. Let's take a look at a objective-c example and get a better idea:

 nsarray *arr1 = @[@ "Cat", @ "Hat", @ "app"];nsarray *arr2 = @[@" Cat ", @" Hat ", @" app "]; nslog (@ "Result%i", (arr1 = = arr2)); //result 0nslog (@ "Result%i", [ ARR1 ISEQUALTOARRAY:ARR2]); //result 1            

In the above code, we have defined two arrays,arr1 and arr2 , which hold the same elements in both arrays. Next we compare them equally and output the results. The first time we used = = equals number to compare, the result of the return is 0, that is to say, the comparison failed. The reason to believe that some experienced students should understand, because in the objective-c = = comparison is a reference, because arr1 and arr2 are two different objects, so even if their values are the same, but their references are not the same. So = = comparison will fail. The second comparison is Nsarray's Isequaltoarray method, which is used to compare values because the values of the two arrays are the same, so the isequaltoarray comparison method returns 1.

<!--more--

equatable Protocol

We learned about the workings of the equality operation through OBJECTIVE-C, including the value equality and reference equality. Now let's go back to Swift. I believe that the students who have OBJECTIVE-C experience will be looking for isequal method, but will find that there is no isequal definition in Swift's native class.

If you want to have a more in-depth understanding of isequal, this article equality the detailed explanation. We don't have too much of a narrative here.

Swift does not provide a definition of the Iequal method, but instead uses an overloaded operator to handle equality judgments in a more natural way. Overloaded == operators are done through the Equatable protocol. We implement the overloads of the operators by implementing the methods in this protocol.

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

Swift has implemented its own array classes, called Array , about Array types, and this article has a detailed description of the Swift tips-array type. The types in Swift Array implement the Equatable protocol, so we can Array compare instances of types by == operator:

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

We have seen that the effect of direct use in Swift == isEqual: is the same as the actual effect of the method in Objective-c. They all compare the values. This feature of Swift is slightly different from objective-c. Almost all of Swift's native classes implement the Equatable protocol.

implementing the Equatable protocol

We now understand the agreement in Swift Equatable . It is believed that careful classmates have discovered that we can compare instances in Swift because the == object of this symbolic operation implements the Equatable protocol. What if we compare the use of objects that do not implement this Protocol == ? We can take a look at this piece of code:

In the above code, we define a Name class and instantiate the two objects of this class john copy . Then we used == to compare the two, then the compiler error. The reason is that our class does not implement the Equatable protocol.

So here's a little bit of a change to 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 modification, we implemented the Equatable protocol and implemented the func ==(lhs: Name, rhs: Name) -> Bool method. The firstName lastName two Name objects are considered equal only if they are equal to each other.

After this modification, we can continue to use our previous judgments:

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

This time, the if method in the statement print was executed successfully.

Now we know that most of the classes in Swift have their own == implementations of the operators. So what if we want to compare the references of two objects to equality Now?

We can use the ObjectIdentifier class to get the reference identity of the object, and we explicitly call the constructor of the class to get the object's reference and compare it:

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

We used to ObjectIdentifier get the reference address of the object, and we ObjectIdentifier implemented the protocol itself, Equatable so we ObjectIdentifier can compare the converted objects to == determine whether the application is the same.

comparable

We have just introduced the Equatable agreement, and it has a protocol associated with it Comparable . Equatablea protocol is a comparison of equality. Instead, the Comparable order is compared. For example, a Double class in Swift implements the Comparable protocol:

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

Implement the Comparable class of the protocol, you can use >,<,<=,>= these operators to compare. The definition of this agreement is as follows:

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

Do you think that to achieve the comparison operation, we have to implement all the methods in this. We might as well take a few minutes to look carefully at the definition of the agreement and think about it.

    1. First of all, there are four sequential comparison operators,,, <= >= > < can you look at this protocol, as if the definition of < is less?
    2. Then, we analyze the logical relationship of these operators, >= actually is a side > == -by-side relationship, if we implement the two operators, the actual >= logic is clear. The >= logic of this operator is generally the statement: return lhs > rhs || lhs == rhs .

By the short analysis above, did we find a pattern? In fact, we can introduce the logic of other operators as long as we implement some operators. For example, with the definition of the interface above, Comparable <= and > These two operators, we just need to implement one to deduce the other. For example, if we implement the > operator, then the ' <= ' operator only needs to reverse the previous function.

So, the <= implementation of our function requires just a similar implementation:

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

Think about it, in fact, as long as the implementation == and < operators, the other operators can be deduced through these two:

    1. >= can be < deduced through the logical inversion and == the logic or operation together.
    2. > can be < deduced by the logical inversion.
    3. <= can be < == deduced through the logic or operation of the.

About this knowledge, there is a concept called strict full order , interested students can read.

So now the problem again, we actually as long as == the implementation and < the logic of the method can complete the comparison operation, then the implementation of the other operators code, is actually the same. It seems a bit redundant.

And Swift is solving this problem for us, providing us with the default implementation of the agreement, and looking closely at the Swift documentation, we will find that in addition to the Comparable protocol, a protocol is defined _Comparable , and the former inherits from the latter. _Comparablethe agreement is defined as follows:

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

We found that just what we lost < here was found. _Comparableis an example of the default protocol implementation mechanism provided in Swift. The _Comparable default implementations for several other operators are provided in the Protocol >=,>,<= .

Since Comparable both the self _Comparable and Equatable the protocol are inherited, we only need to implement the < == two operators to complete the implementation of the comparison operation. Let's look at an example:

ClassName:Comparable {var firstName:Stringvar lastName:StringInit (firstName First:String,lastname Last:String) {Self.firstname = FirstSelf.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)TruePrint (John <= Jack)TruePrint (John = = Jack)FalsePrint (John > Jack)FalsePrint (John < Jack)//falseprint (Jack < Mary) // Trueprint (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 "}]    /span>          

We are here to implement the Comparable protocol completely, we define a Name class, and implement the < and == protocol methods, one from the protocol _Comparable and one from Equatable the protocol. The Comparable three comparison methods in the protocol already _Comparable provide a default implementation in, so we don't have to do it all over again. (Note the underscore difference between the two comparable and _comparable, which is two different protocols.) )

hashable

The last one to mention is the hashable protocol. We should not be unfamiliar with the concept of Dictionary , so if an object wants to be a Dictionary key , then it needs to implement hashable Agreement.

The following classes in Swift implement the hashable protocol by default:

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

So instances of these classes can be used as Dictionary keys. Let's take a look at the definition of the hashable protocol:

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

The definition is very simple, we only need to implement hashValue the calculation method to define the hash value. On the optimization of the hash value we are another subject, so we only do a simple discussion here, will use the property of the class hash value again or operation to calculate the new hash value. Or take 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 key to the dictionary:

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 the three Protocols in Swift, Equatable Comparable Hashable Although we don't usually pay much attention to these protocols, but in our development work, they are no longer playing a role, our if statements, sorting operations, dictionaries and arrays of operations, are related to these several protocols. Most of the classes in Swift are basically implementing these protocols. It can be said that although we often forget them, but they are constantly around us. Knowing them will certainly help us a lot.

Swift Explore-A little exploration of the isequal in Swift

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.