Generic types can gain methods only when their type arguments meet a constraint.

Add behavior for one element type

bonus
constrained_extensions.swift
Replay: real traced execution (multi-file project)
extension Array where Element == Int {
    func total() -> Int {
        var sum = 0
        for value in self {
            sum += value
        }
        return sum
    }
}

let bonus = 5
let scores = [2, 4, bonus]
let total = scores.total()
let message = "total=\(total)"

print(message)
extension Array where Element == Int {
    func total() -> Int {
        var sum = 0
        for value in self {
            sum += value
        }
        return sum
    }
}

let bonus = 0
let scores = [2, 4, bonus]
let total = scores.total()
let message = "total=\(total)"

print(message)
extension Array where Element == Int {
    func total() -> Int {
        var sum = 0
        for value in self {
            sum += value
        }
        return sum
    }
}

let bonus = 10
let scores = [2, 4, bonus]
let total = scores.total()
let message = "total=\(total)"

print(message)
  1. bonus ← 5, scores ← [2, 4, 5]

    11let bonus→ 5 = 5  //@bonus=0, 1012let scores→ [2, 4, 5] = [2, 4, bonus5]13let total = scores[2, 4, 5].total()14let message = "total=\(total)"
  2. sum ← 0

    1extension Array where Element == Int {2    func total() -> Int {3        var sum→ 0 = 04        for value in self {
  3. sum ← 2

    pass 1 of 3
    3var sum = 04for value2 in self {5    sum→ 2 += value26}
    All 3 passes — pass 1 is the card above
    passvaluesum
    120 2
    242 6
    356 11
  4. return sum

    6    }7    return sum118}
  5. total ← 11, message ← total=11

    12let scores = [2, 4, bonus]13let total→ 11 = scores[2, 4, 5].total()14let message→ total=11 = "total=\(total11)"1516print(messagetotal=11)
    outputtotal=11
  1. bonus ← 0, scores ← [2, 4, 0]

    11let bonus→ 0 = 012let scores→ [2, 4, 0] = [2, 4, bonus0]13let total = scores[2, 4, 0].total()14let message = "total=\(total)"
  2. sum ← 0

    1extension Array where Element == Int {2    func total() -> Int {3        var sum→ 0 = 04        for value in self {
  3. sum ← 2

    pass 1 of 3
    3var sum = 04for value2 in self {5    sum→ 2 += value26}
    All 3 passes — pass 1 is the card above
    passvaluesum
    120 2
    242 6
    306
  4. return sum

    6    }7    return sum68}
  5. total ← 6, message ← total=6

    12let scores = [2, 4, bonus]13let total→ 6 = scores[2, 4, 0].total()14let message→ total=6 = "total=\(total6)"1516print(messagetotal=6)
    outputtotal=6
  1. bonus ← 10, scores ← [2, 4, 10]

    11let bonus→ 10 = 1012let scores→ [2, 4, 10] = [2, 4, bonus10]13let total = scores[2, 4, 10].total()14let message = "total=\(total)"
  2. sum ← 0

    1extension Array where Element == Int {2    func total() -> Int {3        var sum→ 0 = 04        for value in self {
  3. sum ← 2

    pass 1 of 3
    3var sum = 04for value2 in self {5    sum→ 2 += value26}
    All 3 passes — pass 1 is the card above
    passvaluesum
    120 2
    242 6
    3106 16
  4. return sum

    6    }7    return sum168}
  5. total ← 16, message ← total=16

    12let scores = [2, 4, bonus]13let total→ 16 = scores[2, 4, 10].total()14let message→ total=16 = "total=\(total16)"1516print(messagetotal=16)
    outputtotal=16
constrained extension A constrained extension keeps specialized behavior available only for matching generic instantiations.