← Back to Swift Course | Chapter 12: Generics & Advanced Types | Lesson 5 of 7

where Clauses in Generics

A where clause in generics adds extra fine-print rules about the types being used, beyond the basic constraints already given.
Syntax
swift
func functionName<A: Sequence, B: Sequence>(_ a: A, _ b: B) where A.Element == B.Element {
    // both hold the same element type
}

extension Type where Element: Comparable {
    func method() { }
}

Using where to Relate Two Generic Types

A where clause can require that two separate generic sequences contain elements of the exact same type, which plain angle-bracket constraints alone can't express.

Example: Using where to Relate Two Generic Types

markup
func printMatchingPairs<A: Sequence, B: Sequence>(_ first: A, _ second: B) where A.Element == B.Element, A.Element: Equatable {
    for (a, b) in zip(first, second) where a == b {
        // Print "Match: \(a)" to the console
        print("Match: \(a)")
    }
}
printMatchingPairs([1, 2, 3], [3, 2, 1])

A where Clause on an Extension

An extension can be constrained with where to only apply when the generic type meets a specific condition, such as its elements being comparable.

Example: A where Clause on an Extension

markup
// Extend `Array` with additional functionality
extension Array where Element: Comparable {
    // Define the function `isSorted` with no parameters and returning a Bool
    func isSorted() -> Bool {
        // Loop over `1..<count where self[i] < self[i - 1]`, binding each item to `i`
        for i in 1..<count where self[i] < self[i - 1] {
            // Return `false` from this function
            return false
        }
        // Return `true` from this function
        return true
    }
}
// Print `[1, 2, 3].isSorted()` to the console
print([1, 2, 3].isSorted())
// Print `[3, 1, 2].isSorted()` to the console
print([3, 1, 2].isSorted())
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Confusing this generics where (adding constraints on generic types) with the loop/switch where from earlier chapters; both filter, but in very different contexts.
  2. Trying to require a relationship between two different generic placeholders (e.g. their elements must match) without a where clause to express it.
  3. Overloading a function signature with constraints that a simpler where Self.Element == ... clause would express more clearly for extension methods.
Chapter Summary
  • A where clause after a generic parameter list adds additional constraints.
  • It's commonly used to require two different generic types share a related requirement.
  • where clauses are especially useful in extensions constrained to specific generic instantiations.
  • They keep the base generic declaration simple while layering on precise requirements where needed.
🔒

Chapter Quiz — Complete all 7 topics to unlock

0/7 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.