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
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
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])
Login to try C/C++/Java/PHP code in the editor
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
// 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())
Login to try C/C++/Java/PHP code in the editor
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
- Confusing this generics
where(adding constraints on generic types) with the loop/switchwherefrom earlier chapters; both filter, but in very different contexts. - Trying to require a relationship between two different generic placeholders (e.g. their elements must match) without a
whereclause to express it. - Overloading a function signature with constraints that a simpler
where Self.Element == ...clause would express more clearly for extension methods.
Chapter Summary
- A
whereclause after a generic parameter list adds additional constraints. - It's commonly used to require two different generic types share a related requirement.
whereclauses 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: