Generics: reuse an algorithm while keeping types
Generics: reuse an algorithm while keeping types
A library helper should return the first item whether it receives names or marks. Generics describe an algorithm in terms of a placeholder type while preserving the actual type used at each call. This avoids treating every value as untyped Any.
What you’ll learn
- Trace a type-preserving generic call.
- Identify when an algorithm needs an additional protocol constraint.
Generics: reuse an algorithm while keeping types in the example
Placeholder type
A library helper should return the first item whether it receives names or marks.
Placeholder typeConcrete call type
The name T is a type parameter, not a runtime variable.
Concrete call typeType-preserving result
The first call specializes the relationship for integers, so its optional contains an Int.
Type-preserving result
How generics: reuse an algorithm while keeping types works
The name T is a type parameter, not a runtime variable. Constraints such as T: Comparable require operations the body needs. Returning T? expresses that an empty input may have no first value while retaining the element’s actual type.
Work through generics: reuse an algorithm while keeping types
Save this complete program as main.swift and run it with the Swift toolchain. No separate input file is needed.
Swift · complete program
func firstItem<T>(_ items: [T]) -> T? { items.first }
print(firstItem([80, 90]) ?? -1)
print(firstItem(["Diya", "Saira"]) ?? "Nobody")Expected output
80
DiyaFollow the execution
The first call specializes the relationship for integers, so its optional contains an Int. The second preserves String. The same source algorithm works for both because reading an array’s first element does not require arithmetic or comparison.
Try this program in the Swift compiler. Paste the complete source above.
Practice: Generics: reuse an algorithm while keeping types
Your task: Why can this unconstrained T not automatically be added with +?
Swift · complete program
func firstItem<T>(_ items: [T]) -> T? { items.first }
print(firstItem([80, 90]) ?? -1)
print(firstItem(["Diya", "Saira"]) ?? "Nobody")Worked answer
The generic declaration does not promise an addition operation. Add a suitable protocol constraint for the intended operation instead of assuming all possible types behave like Int.
Require the operations the algorithm uses
Generic constraints communicate relationships and available operations; they do not mean an algorithm is correct for every domain. Use associated types and where clauses when necessary, but prefer a clear concrete type when flexibility serves no real caller.
Check your decision
Require the operations the algorithm uses
The generic declaration does not promise an addition operation. Add a suitable protocol constraint for the intended operation instead of assuming all possible types behave like Int. Generic constraints communicate relationships and available operations; they do not mean an algorithm is correct for every domain.
Further reading: official Swift language guide.
Reaching the recap and completing the quizzes are separate milestones.