6 ways to use "where" clause in Swift

Mar 30, 2023#swift#ios

The where clause in Swift is a way to specify additional constraints on generic types, functions, associated types, or control flow statements. You can use the where keyword followed by an expression to require that a generic parameter conforms to a protocol, inherits from a class, or is equal to a specific type. It can be used in different contexts, such as:

  1. In a for-in loop, to filter the elements of a collection or sequence based on a condition.
let names = ["Alice", "Bob", "Charlie", "David"]
for name in names where name.count > 4 {
  print (name) // Alice, Charlie, David
}
  1. In a switch statement, to match cases based on a condition.
let age = 25
switch age {
case let x where x < 18:
  print ("You are a minor.")
case let x where x >= 18 && x < 65:
  print ("You are an adult.")
case let x where x >= 65:
  print ("You are a senior.")
default:
  print ("Invalid age.")
}
  1. In a generic function, to add constraints to generic parameters.
protocol Printable {
  func print()
}

func printBoth<P1: Printable, P2: Printable>(_ p1: P1, _ p2: P2) where P1 == P2 {
  p1.print()
  p2.print()
}
  1. In an extension declaration, to add constraints to the extended type or its associated types.
extension Array where Element: Hashable {
  func removeDuplicates () -> [Element] {
    var set = Set<Element> ()
    return self.filter { set.insert ($0).inserted }
  }
}
  1. In a protocol declaration, to add constraints to an associated type.
protocol Stack {
  associatedtype Element where Element: CustomStringConvertible
  mutating func push (_ element: Element)
  mutating func pop () -> Element?
}
  1. In a constrained existential type declaration, to add constraints to the existential type using generic parameters or where clauses.
let shapes: [any Shape where Color == UIColor] = [Circle(radius: 10), Square(side: 5)]