Type Constraints
A type constraint is a rule that says a generic placeholder can only be filled in by types that meet a certain requirement, like "must be comparable."
In this page:
Syntax
func functionName<T: ProtocolName>(_ items: [T]) -> T? {
// can use what ProtocolName provides, e.g. < for Comparable
}
Constraining to Comparable
Adding : Comparable to a generic placeholder allows the function to use comparison operators like < and >, which aren't guaranteed on an unconstrained type.
Example: Constraining to Comparable
func findLargest<T: Comparable>(_ items: [T]) -> T? {
guard var largest = items.first else { return nil }
// Loop over `items where item > largest`, binding each item to `item`
for item in items where item > largest {
largest = item
}
// Return `largest` from this function
return largest
}
// Print `findLargest([3, 7, 2, 9, 4]) as Any` to the console
print(findLargest([3, 7, 2, 9, 4]) as Any)
// Print `findLargest(["banana", "apple", "cherry"]) as Any` to the console
print(findLargest(["banana", "apple", "cherry"]) as Any)
Login to try C/C++/Java/PHP code in the editor
Constraining to a Custom Protocol
A generic placeholder can also be constrained to any custom protocol, requiring conforming types to implement its specific requirements.
Example: Constraining to a Custom Protocol
// Define a protocol `Summable` describing required behavior
protocol Summable {
static func + (lhs: Self, rhs: Self) -> Self
static var zero: Self { get }
}
// Extend `Int` with additional functionality
extension Int: Summable {
static var zero: Int { 0 }
}
func total<T: Summable>(_ items: [T]) -> T {
// Declare a mutable variable `result`, initialized to `T.zero`
var result = T.zero
// Loop over `items`, binding each item to `item`
for item in items {
result = result + item
}
// Return `result` from this function
return result
}
// Print `total([1, 2, 3, 4])` to the console
print(total([1, 2, 3, 4]))
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
- Writing a generic function that uses
<or==on its placeholder type without constraining it toComparableorEquatablefirst -- the compiler will reject unconstrained comparisons. - Confusing a class-inheritance constraint (
T: SomeClass) with a protocol constraint (T: SomeProtocol); both use the same colon syntax but mean different things. - Over-constraining a generic function with requirements it doesn't actually need, unnecessarily limiting what types can be used.
Chapter Summary
- A constraint restricts a generic placeholder to types conforming to a protocol or inheriting a class.
- Constraints are written after the placeholder name with a colon, like
<T: Comparable>. - Constraints let you use operations (like
<or==) that aren't available on every possible type. - Multiple constraints can be combined using
&or awhereclause.
🔒
Chapter Quiz — Complete all 7 topics to unlock
0/7 topics done
Complete these topics first: