Chapters

Hide chapters

Swift Cookbook

Live Edition · Multiplatform · Swift · Editor agnostic

Use Self-requirement in Protocols in Swift
Written by Team Kodeco

A protocol in Swift is a set of rules that a class, struct or enum must follow. Sometimes you need to make sure that the class or struct that conforms to a protocol must implement a certain method or property itself, instead of using an extension. This is where the Self keyword comes in.

Let’s take a look at an example. You have a protocol called SelfPrintable which requires a method called printSelf(). This method should return a string.

protocol SelfPrintable {
  func printSelf() -> String
}

Now you have a class called MyClass which conforms to the SelfPrintable protocol.

class MyClass: SelfPrintable {
  var name: String
  init(name: String) {
    self.name = name
  }
  func printSelf() -> String {
    return "My name is \(name)"
  }
}

Now let’s say you want to add a method to the SelfPrintable protocol that checks if two instances of the class that conforms to the protocol are equal. You can do this using an extension and the Self keyword.

extension SelfPrintable where Self: Equatable {
  func isEqual(to other: Self) -> Bool {
    return self == other
  }
}

The Self keyword in the where clause of the extension is used to specify that the extension should only be applied to types that conform to the SelfPrintable protocol and also conform to the Equatable protocol.

The isEqual(to:) function is defined in this extension and it uses the Self keyword in the parameter type to specify that the method should work with the same type that conforms to the SelfPrintable protocol. Inside the function, the self == other comparison is used to check if two instances of the conforming type are equal.

Finally, you’ll make MyClass conform to the Equatableprotocol and implement the == function.

class MyClass: SelfPrintable, Equatable {
  var name: String
  init(name: String) {
    self.name = name
  }
  func printSelf() -> String {
    return "My name is \(name)"
  }
  static func == (lhs: MyClass, rhs: MyClass) -> Bool {
    return lhs.name == rhs.name
  }
}

Now you can create two instances of MyClass and check if they are equal.

let myClassA = MyClass(name: "A")
let myClassB = MyClass(name: "B")
print(myClassA.isEqual(to: myClassB)) // prints "false"

In summary, using the Self keyword in a protocol’s requirement allows you to specify that a method or property must be implemented by the conforming type itself, not just by an extension. This can help to ensure that the class or struct that conforms to the protocol follows the rules of the protocol correctly.

© 2024 Kodeco Inc.