Swift Protocols

Swift Protocols

Define behavior contracts that types adopt, and extend them to add default implementations.


Defining and Conforming to Protocols

protocol defines a blueprint of methods and properties.

Types adopt a protocol by providing implementations.

Syntax:

  • protocol P { var x: Int { get set }; func f() }
  • struct S: P { ... }

Example

protocol Greetable { func greet() -> String }

struct Person: Greetable {
  var name: String
  func greet() -> String { "Hello, \(name)" }
}

let p = Person(name: "Swift")
print(p.greet())

This example demonstrates how a protocol is defined and adopted by a type, and how the type provides an implementation for the protocol’s method.

Tip: Use protocol extensions to provide default method implementations.


Protocol Extensions (Default Implementations)

Provide default behavior for conforming types by adding implementations in a protocol extension.

Example

protocol Describable { func describe() -> String }

extension Describable {
  func describe() -> String { "(no description)" }
}

struct User: Describable { let name: String }

struct Car: Describable {
  let model: String
  func describe() -> String { "Car: \(model)" }
}

let u = User(name: "Morgan")
let c = Car(model: "SwiftMobile")
print(u.describe())
print(c.describe())

This example gives User a default describe() and overrides it in Car.



Protocols with Associated Types

Use associatedtype to make a protocol generic over a placeholder type.

Conformers bind the placeholder to a concrete type.

Example

protocol Container {
  associatedtype Element
  mutating func append(_ item: Element)
  var count: Int { get }
  subscript(i: Int) -> Element { get }
}

struct IntStack: Container {
  private var items: [Int] = []
  mutating func append(_ item: Int) { items.append(item) }
  var count: Int { items.count }
  subscript(i: Int) -> Int { items[i] }
}

func allItemsMatch<C1: Container, C2: Container>(_ c1: C1, _ c2: C2) -> Bool
where C1.Element == C2.Element, C1.Element: Equatable {
  guard c1.count == c2.count else { return false }
  for i in 0..<c1.count { if c1[i] != c2[i] { return false } }
  return true
}

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *