Skip to content
Prepare to Grow

Swift Fundamentals

Generics

Write reusable, type-safe functions and types with generic parameters, constraints, and associated types.

Beginner5 min read2 guided activities

Before you begin

What you will understand

  • Explain why generics preserve type information.
  • Write generic functions and types.
  • Constrain generic parameters with protocols.
  • Recognize generics in common Swift APIs.
01

Learning stage

Concept Explanation

Generics let one implementation work with different concrete types without giving up compile-time safety. A generic parameter such as T is a placeholder that becomes a real type when the function or type is used. Swift can usually infer that type from the arguments.

Constraints describe what a generic value must be able to do. For example, T: Equatable allows an implementation to compare two T values. Use generics when behavior is genuinely independent of the concrete type; use a concrete type when the domain requires one specific representation.

  • Generic parameter: a placeholder such as T.
  • Constraint: a requirement such as T: Equatable.
  • Generic type: Array<Element>, Result<Success, Failure>, and your own containers.
  • Associated type: a protocol placeholder chosen by each conforming type.
02

Learning stage

Syntax & Examples

The function accepts any Equatable element while preserving the array's concrete element type.

Search.swiftswift
func firstIndex<T: Equatable>(of target: T, in values: [T]) -> Int? {
  for (index, value) in values.enumerated() {
    if value == target { return index }
  }
  return nil
}

print(firstIndex(of: "Swift", in: ["iOS", "Swift", "Xcode"]) ?? -1)
print(firstIndex(of: 30, in: [10, 20, 30]) ?? -1)
Expected output: 1 and 2. The compiler creates type-safe uses for String and Int.
03

Learning stage

Real-World Usage

These concepts appear throughout production iOS code. Focus on the requirement each technique communicates.

  • Model reusable loading, caching, decoding, and result containers.
  • Use standard generic collections such as Array, Dictionary, Set, and Result.
  • Constrain reusable APIs to capabilities such as Identifiable, Codable, or Comparable.
04

Learning stage

Common Mistakes

Notice these mistakes early so the compiler and type system can help instead of becoming obstacles.

  • Replacing a clear concrete API with unnecessary generic complexity.
  • Using Any and losing type information when a generic parameter would preserve it.
  • Adding a constraint the implementation does not actually need.
  • Assuming two generic parameters represent the same type without declaring that relationship.
05

Learning stage

Practice Exercises

Work through these activities in a small Xcode project. No embedded playground is required on this site.

Activity 1

Create a generic helper

Write a function that returns the last element of any array as an optional. Test it with strings and integers.

Hint: The return type should use the same generic element type as the input array.

Activity 2

Constrain a generic type

Create a Box<Value> type and an isSame(as:) method available when Value conforms to Equatable.

Hint: Use a constrained extension.

06

Learning stage

Knowledge Check

Answer each question before revealing the explanation.

QUESTION 1

What is the main benefit of generics over Any?

  1. A.They preserve compile-time type information
  2. B.They disable compiler checks
  3. C.They always make code shorter
  4. D.They work only with classes
Reveal answer

They preserve compile-time type information

A generic API remains reusable while the compiler knows the concrete type at each use.

QUESTION 2

Why would a generic function require T: Equatable?

Reveal answer

Because its implementation needs to compare T values with == or !=.

Constraints grant the generic implementation access to specific capabilities.

07

Learning stage

Interview Preparation

Explain the idea in terms of its purpose, behavior, and tradeoffs rather than reciting syntax.

When would you choose a generic API instead of a protocol existential or Any?

Short answer: Choose generics when one implementation should preserve the caller's concrete type and use capabilities expressed through constraints.

Explore the detailed answer

Generics provide compile-time specialization and keep relationships between input and output types. A protocol existential is useful when heterogeneous values need one runtime interface. Any removes useful information and should not be a default escape hatch.

Possible follow-ups

  • • What is a generic constraint?
  • • Where do associated types appear in Swift?
08

Learning stage

Key Takeaways

Generics express reusable algorithms and containers without erasing type information. Add only the constraints the implementation needs and keep concrete APIs concrete when the domain calls for them.

  • Generic parameters stand in for concrete types.
  • Constraints provide required capabilities.
  • Swift's core collections and Result are generic.
  • Generics preserve relationships between input and output types.