Extensions

Reviewed & published by Brayan K

Extensions let you add new methods, computed properties, initializers, and protocol conformances to any type — including Int, String, and Array — without subclassing or editing the original source.

Part of the free Swift course at LearnCodingFast — hands-on lessons with worked examples and the output they print, plus practice exercises and a quick quiz.

What You'll Learn in This Lesson

1️⃣ Adding Methods & Computed Properties

The simplest use of an extension is bolting new behaviour onto an existing type. Here we give Int a computed property and a method — and they read as if they were built in.

// An extension adds new functionality to an EXISTING type — even one you
// didn't write, like Int from the standard library.
extension Int {
    // A new computed property:
    var squared: Int { return self * self }

    // A new method:
    func times(_ task: () -> Void) {
        for _ in 0..<self { task() }
    }
}

print(5.squared)   // 25

3.times {
    print("Hi")
}

2️⃣ Extending Standard-Library Types

You can extend types you don't own. Adding convenience computed properties to String keeps call sites clean and expressive.

// Extensions are great for adding convenient computed properties.
extension String {
    // Is this string a palindrome (reads the same forwards and backwards)?
    var isPalindrome: Bool {
        let cleaned = self.lowercased()
        return cleaned == String(cleaned.reversed())
    }

    // First letter uppercased:
    var capitalizedFirst: String {
        guard let first = self.first else { return self }
        return first.uppercased() + self.dropFirst()
    }
}

print("level".isPalindrome)        // true
print("swift".isPalindrome)        // false
print("hello".capitalizedFirst)    // Hello

3️⃣ Protocol Conformance via Extension

A popular pattern is to declare a type plainly, then add each protocol conformance in its own extension. This keeps the core definition tidy and groups related code.

// A common pattern: declare a type, then add protocol conformance in a
// separate extension to keep things organized.
struct Point {
    let x: Int
    let y: Int
}

// Add Equatable conformance via an extension:
extension Point: Equatable {
    static func == (lhs: Point, rhs: Point) -> Bool {
        return lhs.x == rhs.x && lhs.y == rhs.y
    }
}

// Add a description in yet another extension:
extension Point {
    var label: String { return "(\(x), \(y))" }
}

let a = Point(x: 1, y: 2)
let b = Point(x: 1, y: 2)
print(a == b)        // true
print(a.label)       // (1, 2)

Your turn. Fill in the blanks to extend two standard types.

// 🎯 YOUR TURN — fill in the blanks, then run it in SwiftFiddle.

// 1) Extend Double with a computed property. Replace ___ with the keyword.
___ Double {                 // 👉 replace ___ with 'extension'
    var doubled: Double { return self * 2 }
}
print(3.5.doubled)   // 7.0

// 2) Extend Int with a method 'isEven'. Replace ___ with the keyword 'func'.
extension Int {
    ___ isEven() -> Bool {   // 👉 replace ___ with 'func'
        return self % 2 == 0
    }
}
print(4.isEven())   // true

Pro Tips

Common Errors (and the fix)

📋 Quick Reference

TaskCodeNote
Extend a typeextension Int { … }add members
Computed propvar sq: Int { self*self }no storage
Methodfunc isEven() -> Boolnew behaviour
Conformanceextension P: Equatable { … }organized
Constraintextension Array where Element == Intconditional

Mini-Challenge: Extend Array

No blanks this time — just a brief and an outline. Build it, run it, and check your output against the example in the comments.

// 🎯 MINI-CHALLENGE: extend Array
// 1. Write an extension on Array where Element == Int.
// 2. Add a computed property 'sum' that returns the total of all elements.
//    (Hint: use reduce(0) { $0 + $1 }.)
// 3. Add a method 'doubled()' that returns a new array with each value * 2.
// 4. Test both on [1, 2, 3, 4].
//
// ✅ Expected output:
//    10
//    [2, 4, 6, 8]

// your code here

🎉 Lesson Complete!

Practice quiz

What does an extension let you do?

  • Subclass a final class
  • Delete methods from a type
  • Add new functionality to an existing type
  • Rename a type

Answer: Add new functionality to an existing type. Extensions add new methods, computed properties, initializers, and conformances to existing types.

Which keyword introduces an extension?

  • extension
  • extend
  • category
  • augment

Answer: extension. You write 'extension TypeName { ... }' to extend a type.

Can an extension add STORED properties?

  • Yes, any kind
  • Only for classes
  • Only static stored properties
  • No — only computed properties are allowed

Answer: No — only computed properties are allowed. Extensions cannot add stored properties; they can add computed properties and methods.

Can you extend types you don't own, like Int or String?

  • No, only your own types
  • Yes — you can extend any type, including the standard library's
  • Only in the same file
  • Only structs

Answer: Yes — you can extend any type, including the standard library's. Extensions work on any type, including Int, String, and Array from the standard library.

Can an extension add a computed property?

  • Yes
  • No
  • Only get-only ones to classes
  • Only to protocols

Answer: Yes. Extensions can add computed properties (with get, and optionally set).

Can you add protocol conformance via an extension?

  • No
  • Only at declaration time
  • Yes — extension MyType: SomeProtocol { ... }
  • Only for enums

Answer: Yes — extension MyType: SomeProtocol { ... }. A common pattern is 'extension MyType: SomeProtocol { ... }' to organize conformance separately.

Can an extension add a method to a protocol?

  • No
  • Yes — protocol extensions provide default implementations
  • Only computed properties
  • Only to classes

Answer: Yes — protocol extensions provide default implementations. Protocol extensions add methods that become default implementations for all conformers.

What kind of initializer can an extension add to a struct?

  • A designated init that replaces the memberwise one
  • A deinitializer
  • None
  • A convenience-style init (without removing the memberwise init)

Answer: A convenience-style init (without removing the memberwise init). An extension can add an initializer to a struct while preserving the automatic memberwise initializer.

Do extensions let you override existing methods of a type?

  • Yes, that's their main use
  • No — extensions add new functionality, not override existing members
  • Only in subclasses
  • Only for final types

Answer: No — extensions add new functionality, not override existing members. Extensions add to a type; they are not for overriding a type's existing methods.

Why are extensions useful for code organization?

  • They make code run faster
  • They reduce memory
  • They let you group related methods and conformances into focused chunks
  • They hide a type's properties

Answer: They let you group related methods and conformances into focused chunks. Extensions let you split a type's functionality into logically grouped, readable sections.

Continue this course

Frequently asked questions

What can you add with a Swift extension?

Extensions can add computed instance and type properties, instance and type methods, new initializers, nested types, subscripts, and protocol conformances. What they cannot do is add stored properties or override existing functionality — they only extend a type with new members.

Why can't extensions add stored properties?

Stored properties change a type's memory layout, and an extension may live in a different module than the original type. Allowing it would break binary compatibility and the type's known size. You can, however, add computed properties, which calculate their value on demand without extra storage.

Can I extend types I didn't write, like String or Array?

Yes — that's one of the most useful features. You can extend any type, including the standard library's String, Int, Array, and even types from other frameworks. This lets you add domain-specific helpers (like myString.isPalindrome) as if they were built in.

How do extensions help with protocol conformance?

You can declare conformance in a separate extension, e.g. extension Point: Equatable { ... }. This keeps the main type definition focused on its core data while grouping each protocol's required methods together. Extensions on protocols themselves provide default implementations for all conformers.

Can an extension add an initializer to a struct?

Yes. Adding an initializer in an extension (rather than the original struct body) lets you keep the struct's automatically generated memberwise initializer while also offering your own custom one. If you add a custom init inside the struct body itself, the memberwise initializer is suppressed.