Swift - Extensions



What are Extensions in Swift?

Swift provides a special feature known as extension. Extensions are used to add new functionalities in the existing class, structure, enumeration or protocol type without overriding or modifying the existing code. This feature is useful when we want to extend the functionality of types that we cannot modify, such as third-party libraries, etc. Extensions are static additions to the type they are not dynamic. Also, they cannot add stored properties with default values.

The following are the functionalities provided by the extensions −

  • Adding computed properties and computed type properties

  • Defining instance and type methods

  • Providing new initializers

  • Defining subscripts

  • Defining and using new nested types

  • Making an existing type conform to a protocol

Defining Extensions in Swift

Extensions are declared with the help of the extension keyword.

Syntax

Following is the syntax for the extension −

extension SomeType {
   // Adding new functionality
}

Existing type can also be added with extensions to make it a protocol standard and its syntax is similar to that of classes or structures.

extension SomeType: SomeProtocol, AnotherProtocol {
   // Describe protocol requirements
}

Extensions with Computed Properties

Computed 'instance' and 'type' properties can also be extended with the help of extensions. Computed properties are those properties that do not store a value instead, they provide a getter and setter to retrieve and set other properties and values.

Example

Swift program to demonstrate how to add new functionality in the computed properties using the extension.

// Adding new functionality to the computed property using an extension
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("Addition is \(addition)")
    
let subtraction = 120.sub
print("Subtraction is \(subtraction)")
    
let multiplication = 39.mul
print("Multiplication is \(multiplication)")
    
let division = 55.div
print("Division is \(division)")

let mix = 30.add + 34.sub
print("Mixed Type is \(mix)")

Output

It will produce the following output −

Addition is 103
Subtraction is 110
Multiplication is 390
Division is 11
Mixed Type is 154

Extension with Initializers

Swift provides the flexibility to add new initializers to an existing type using extensions. The user can add their own custom types to extend the types already defined and additional initialization options are also possible. Extensions support only init(). deinit() is not supported by the extensions.

Example

Swift program to demonstrate how to add new functionality in the initializer using the extension.

struct sum {
   var num1 = 100, num2 = 200
}
   
struct diff {
   var no1 = 200, no2 = 100
}
   
struct mult {
   var a = sum()
   var b = diff()
}
   
let calc = mult()
print ("Inside mult block \(calc.a.num1, calc.a.num2)")
print("Inside mult block \(calc.b.no1, calc.b.no2)")
   
let memcalc = mult(a: sum(num1: 300, num2: 500),b: diff(no1: 300, no2: 100))
 
print("Inside mult block \(memcalc.a.num1, memcalc.a.num2)")
print("Inside mult block \(memcalc.b.no1, memcalc.b.no2)")
   
extension mult {
   init(x: sum, y: diff) {
      let X = x.num1 + x.num2
      let Y = y.no1 + y.no2
   }
}  

let a = sum(num1: 100, num2: 200)
print("Inside Sum Block:\( a.num1, a.num2)")   
   
let b = diff(no1: 200, no2: 100)
print("Inside Diff Block: \(b.no1, b.no2)")

Output

It will produce the following output −

Inside mult block (100, 200)
Inside mult block (200, 100)
Inside mult block (300, 500)
Inside mult block (300, 100)
Inside Sum Block:(100, 200)
Inside Diff Block: (200, 100)

Extension with Methods

New instance methods and type methods can be added further to the subclass with the help of extensions.

Example

Swift program to demonstrate how to add new functionality in the methods using the extension.

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

4.topics({
   print("Inside Extensions Block")       
})    
    
3.topics({
   print("Inside Type Casting Block")       
})  

Output

It will produce the following output −

Inside Extensions Block
Inside Extensions Block
Inside Extensions Block
Inside Extensions Block
Inside Type Casting Block
Inside Type Casting Block
Inside Type Casting Block

Extension with Mutating Instance Methods

We can also add new functionality in the mutating instance methods of structure and enumeration using the extension.

Example

Swift program to demonstrate how to add new functionality in the mutating methods using the extension.

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

var Trial1 = 3.3
Trial1.square()
print("Area of circle is: \(Trial1)")

var Trial2 = 5.8
Trial2.square()
print("Area of circle is: \(Trial2)")

var Trial3 = 120.3
Trial3.square()
print("Area of circle is: \(Trial3)")

Output

It will produce the following output −

Area of circle is: 34.210935
Area of circle is: 105.68006
Area of circle is: 45464.070735

Extension with Subscripts

Adding new subscripts to already declared instances can also be possible with extensions.

Example

Swift program to demonstrate how to add new functionality in the subscript using the extension.

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])

Output

It will produce the following output −

2
6
5

Extension with Nested Types

Nested types for class, structure and enumeration instances can also be extended with the help of extensions.

Example

Swift program to demonstrate how to add new functionality in the nested types using the extension.

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(numb: [0, 1, 2, 3, 4, 7])

Output

It will produce the following output −

10 
20 
30 
40 
50 
50
Advertisements