Chapters

Hide chapters

Swift Cookbook

Live Edition · Multiplatform · Swift · Editor agnostic

Use Where Clauses with Swift Generics
Written by Team Kodeco

In Swift, you can use where clauses to specify additional requirements for generic types and associated types. A where clause is added by placing the where keyword after the type parameter list, followed by one or more constraints.

Here’s an example of how to use where clauses with Swift generics:

protocol Container {
  associatedtype Item
  var items: [Item] { get set }
  mutating func append(_ item: Item)
  mutating func pop() -> Item
  var count: Int { get }
}

struct Stack<T>: Container {
  var items = [T]()
  mutating func append(_ item: T) {
    items.append(item)
  }
  mutating func pop() -> T {
    return items.removeLast()
  }
  var count: Int {
    return items.count
  }
}

func popAllAndTestMatch<C1: Container, C2: Container>(
  _ someContainer: inout C1,
  _ anotherContainer: inout C2
) -> Bool where C1.Item == C2.Item, C1.Item: Equatable {
  if someContainer.count != anotherContainer.count {
    return false
  }
  for _ in 0..<someContainer.count {
    if someContainer.pop() != anotherContainer.pop() {
      return false
    }
  }
  return true
}

var stackOfStrings1 = Stack<String>()
stackOfStrings1.append("uno")
stackOfStrings1.append("dos")
stackOfStrings1.append("tres")

var stackOfStrings2 = Stack<String>()
stackOfStrings2.append("uno")
stackOfStrings2.append("dos")
stackOfStrings2.append("tres")

if popAllAndTestMatch(&stackOfStrings1, &stackOfStrings2) {
  print("All items match.")
} else {
  print("Not all items match.")
}
// Output: All items match

In this example, the popAllAndTestMatch function is a generic function that takes two containers, C1 and C2, as its parameters. The function uses where clauses to specify that the items in both containers must be of the same type (C1.Item == C2.Item) and that the items must be equatable (C1.Item: Equatable).

The function compares the two containers by popping items from each container and comparing them. If the number of items in the two containers isn’t the same, the function returns false. If the number of items is the same, the function pops items from each container one by one and compares them. If all items are the same, the function returns true.

In this example, you created two Stack structures with the same string values, then pass them as arguments to the popAllAndTestMatch function. Since the function returns true, indicating that all items match, the output is “All items match.”

It’s important to note that the where clause is used to create constraints on the type parameter, allowing you to use certain methods or properties on the type, in this case the Equatable protocol. This can make your code more flexible and reusable.

© 2024 Kodeco Inc.