Equatable and Comparable Protocol

Introduction

Welcome to Lesson 4 of Advanced Swift. Since Chapter 4, you’ve learned practical aspects of using protocols along with associated types and extensions. However, you haven’t looked into how native types such as String, Int conform to default protocols pre-designed by Swift engineers.

Problem

Understand, “Swift is a protocol oriented language”

Equatable

String, Int, Double, and other native types conform to Equatable. Any type conforms to Equatable has a required method below.

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

Custom Struct

Let us create a struct, Blog and conforms to Equatable.

  1. struct Blog {
  2. let author: String
  3. let title: String
  4. }
  5. extension Blog: Equatable {
  6. static func ==(lhs: Blog, rhs: Blog) -> Bool {
  7. return lhs.author == rhs.author && lhs.title == rhs.title
  8. }
  9. }

Blog objects have the == infix operator.

  1. let firstArticle = Blog(author: "Bob Lee", title: "Protocol AssociatedType")
  2. let secondArticle = Blog(author: "Bob Lee", title: "Type Eraser")
  3. firstArticle == secondArticle // false

Custom Tuple

Let us create another struct called GridPoint.

  1. struct GridPoint {
  2. var grid: (Int, Int)
  3. init(_ numberOne: Int, _ numberTwo: Int) {
  4. grid = (numberOne, numberTwo)
  5. }
  6. }

Let GridPoint conforms to Equatable.

  1. extension GridPoint: Equatable {
  2. static func ==(lhs: GridPoint, rhs: GridPoint) -> Bool {
  3. return lhs.grid.0 == rhs.grid.0 && lhs.grid.1 == rhs.grid.1
  4. }
  5. }

Let us check.

  1. let pointOne = GridPoint(4, 10)
  2. let pointTwo = GridPoint(4, 10)
  3. pointOne == pointTwo // true

Comparable

Most number types such as Int, Double, conform to Comparable.

  1. 10 > 5 // true
  2. 10 <= 4 // false
  3. 123.1 >= 100.0 // false

Required Method

Comparable inherits Equatable. Therefore, Self has to implement == as well.

  1. public protocol Comparable : Equatable {
  2. public static func <(lhs: Self, rhs: Self) -> Bool
  3. public static func <=(lhs: Self, rhs: Self) -> Bool
  4. public static func >=(lhs: Self, rhs: Self) -> Bool
  5. public static func >(lhs: Self, rhs: Self) -> Bool
  6. }

Enum with Comparable

Create an enum called, OS.

  1. enum OS {
  2. case iOS
  3. case android
  4. }
  5. extension OS: Comparable {
  6. static func ==(lhs: OS, rhs: OS) -> Bool {
  7. return lhs == rhs
  8. }
  9. static func <(lhs: OS, rhs: OS) -> Bool {
  10. return rhs == .iOS ? true : false
  11. }
  12. static func <=(lhs: OS, rhs: OS) -> Bool {
  13. return false
  14. }
  15. static func >=(lhs: OS, rhs: OS) -> Bool {
  16. return false
  17. }
  18. static func >(lhs: OS, rhs: OS) -> Bool {
  19. return lhs == .iOS ? true: false
  20. }
  21. }

Let us test.

  1. let iOS = OS.iOS
  2. let android = OS.android
  3. // iOS < android // false
  4. // iOS <= android // false
  5. // iOS >= android // false
  6. // iOS > android // true
  7. // android > iOS // false
  8. // android >= iOS // false
  9. // android <= iOS // false
  10. // android < iOS // true

Important: iOS can not be equal to Android. It can be only greater.

Source Code

8004_equatable_comparable.playground

Resources

swiftdoct.org/Array

Conclusion

We’ve taken a look at two popular protocols: equatable and comparable. You’ve learned that native Swift types such as Int, Double, conform to them and have required operators. After, you’ve learned how to create your own types that conform to equatable and comparable to provide the same effect with the native types.

In the following lesson, you will learn protocols that make a for-in loop possible.

Note: Learn Swift with Bob is available on Udemy. If you wish to receive a discount link, you may sign up here.