Easy Tutorial
❮ Swift Inheritance Swift Properties ❯

Swift Extensions

Extensions add new functionality to an existing class, structure, or enumeration type.

Extensions can add new functionality to a type, but they cannot override existing functionality.

Extensions in Swift can:

Syntax

Extensions are declared using the extension keyword:

extension SomeType {
    // New functionality to add to SomeType goes here
}

An extension can extend an existing type to make it adopt one or more protocols, with the following syntax:

extension SomeType: SomeProtocol, AnotherProtocol {
    // Protocol implementations go here
}

Computed Properties

Extensions can add computed instance properties and computed type properties to existing types.

Example

The following example adds five computed instance properties to the Int type and extends its functionality:

extension Int {
   var add: Int { return self + 100 }
   var sub: Int { return self - 10 }
   var mul: Int { return self * 10 }
   var div: Int { return self / 5 }
}

let addition = 3.add
print("Value after addition: \(addition)")

let subtraction = 120.sub
print("Value after subtraction: \(subtraction)")

let multiplication = 39.mul
print("Value after multiplication: \(multiplication)")

let division = 55.div
print("Value after division: \(division)")

let mix = 30.add + 34.sub
print("Result of mixed operations: \(mix)")

Output of the above program is:

Value after addition: 103
Value after subtraction: 110
Value after multiplication: 390
Value after division: 11
Result of mixed operations: 154

Initializers

Extensions can add new initializers to existing types.

This allows you to extend other types to accept your own custom types as initializer parameters, or to provide additional initialization options not included in the type's original implementation.

Extensions can add new convenience initializers to a class, but they cannot add new designated initializers or deinitializers.

struct Sum {
    var num1 = 100, num2 = 200
}

struct Diff {
    var no1 = 200, no2 = 100
}

struct Mult {
    var a = Sum()
    var b = Diff()
}

extension Mult {
    init(x: Sum, y: Diff) {
        _ = x.num1 + x.num2
        _ = y.no1 + y.no2
    }
}

let a = Sum(num1: 100, num2: 200)
let b = Diff(no1: 200, no2: 100)

let getMult = Mult(x: a, y: b)
print("getMult sum(\(getMult.a.num1, getMult.a.num2))")
print("getMult diff(\(getMult.b.no1, getMult.b.no2))")

Output of the above program is:

getMult sum(100, 200)
getMult diff(200, 100)

Methods

Extensions can add new instance methods and type methods to existing types.

The following example adds a new instance method called topics to the Int type:

extension Int {
   func topics(summation: () -> ()) {
      for _ in 0..<self {
         summation() 
      }
   }
}  

4.topics({
   print("Inside extension block")       
})    

3.topics({
   print("Inside type casting block")       
})

Output of the above program is:

Inside extension block
Inside extension block
Inside extension block
Inside extension block
Inside type casting block
Inside type casting block
Inside type casting block

The topics method takes a single argument of type () -> (), indicating that the function has no parameters and returns no value.

After defining this extension, you can call the topics method on any integer, which will execute a task multiple times.

Mutable Instance Methods

Instance methods added through extensions can also modify the instance itself.

Methods in structures and enumerations that modify self or its properties must mark the instance method as mutating, just like mutating methods from the original implementation.

Example

The following example adds a new mutating method called square to Swift's Double type, which calculates the square of the original value:

extension Double {
   mutating func square() {
      let pi = 3.1415
      self = pi * self * self
   }
}

var Trial1 = 3.3
Trial1.square()
print("The area of the circle is: \(Trial1)")

var Trial2 = 5.8
Trial2.square()
print("The area of the circle is: \(Trial2)")

var Trial3 = 120.3
Trial3.square()
print("The area of the circle is: \(Trial3)")

The output of the above program is:

The area of the circle is: 34.210935
The area of the circle is: 105.68006
The area of the circle is: 45464.070735

Subscripts

Extensions can add new subscripts to an existing type.

Example

The following example adds an integer subscript to Swift's built-in Int type. This subscript [n] returns the decimal digit:

extension Int {
   subscript(var multtable: Int) -> Int {
      var no1 = 1
      while multtable > 0 {
         no1 *= 10
         --multtable
      }
      return (self / no1) % 10
   }
}

print(12[0])
print(7869[1])
print(786543[2])

The output of the above program is:

2
6
5

Nested Types

Extensions can add new nested types to existing classes, structures, and enumerations:

extension Int {
   enum calc {
      case add
      case sub
      case mult
      case div
      case anything
   }

   var print: calc {
      switch self {
         case 0:
            return .add
         case 1:
            return .sub
         case 2:
            return .mult
         case 3:
            return .div
         default:
            return .anything
       }
   }
}

func result(numb: [Int]) {
   for i in numb {
      switch i.print {
         case .add:
            print(" 10 ")
          case .sub:
            print(" 20 ")
         case .mult:
         print(" 30 ")
         case .div:
         print(" 40 ")
         default:
         print(" 50 ")
      }
   }
}

result([0, 1, 2, 3, 4, 7])

The output of the above program is:

10 
 20 
 30 
 40 
 50 
 50
❮ Swift Inheritance Swift Properties ❯