ProgramGuru

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

  1. Placeholder type

    A library helper should return the first item whether it receives names or marks.

    Placeholder type
  2. Concrete call type

    The name T is a type parameter, not a runtime variable.

    Concrete call type
  3. Type-preserving result

    The first call specializes the relationship for integers, so its optional contains an Int.

    Type-preserving result
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.

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
Diya

Follow 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

Why can this unconstrained T not automatically be added with +?
Choose one answer. You can try again.

Answer and explanation

The generic declaration does not promise an addition operation.

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

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.

    Next lesson: Access control and protected mutation →