Swift extension


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

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

Extensions in Swift can:

  • Add computed properties and computed static properties

  • Define instance methods and types Methods

  • Provide new constructors

  • Define subscripts

  • Define and use new Nested types

  • Make an existing type conform to a protocol

Syntax

Extension declaration using keywordsextension

extension SomeType {
    // 加到SomeType的新功能写到这里
}

An extension can extend an existing type so that it can adapt to one or more protocols. The syntax format is as follows:

extension SomeType: SomeProtocol, AnotherProctocol {
    // 协议实现写到这里
}

Computed attributes

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

Example

The following example adds 5 calculated instance attributes 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("加法运算后的值:\(addition)")
    
let subtraction = 120.sub
print("减法运算后的值:\(subtraction)")
    
let multiplication = 39.mul
print("乘法运算后的值:\(multiplication)")
    
let division = 55.div
print("除法运算后的值: \(division)")

let mix = 30.add + 34.sub
print("混合运算结果:\(mix)")

The output result of the above program execution is:

加法运算后的值:103
减法运算后的值:110
乘法运算后的值:390
除法运算后的值: 11
混合运算结果:154

Constructor

Extensions can add new constructors to existing types.

This allows you to extend other types, pass your own custom types as constructor parameters, or provide additional initialization options not included in the original implementation of the type.

Extensions can add a new convenience initializer init() to a class, but they cannot add a new designated constructor or destructor deinit() to a class.

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 ("mult 模块内 \(calc.a.num1, calc.a.num2)")
print("mult 模块内 \(calc.b.no1, calc.b.no2)")

let memcalc = mult(a: sum(num1: 300, num2: 500),b: diff(no1: 300, no2: 100))

print("mult 模块内 \(memcalc.a.num1, memcalc.a.num2)")
print("mult 模块内 \(memcalc.b.no1, memcalc.b.no2)")

extension mult {
    init(x: sum, y: diff) {
        _ = x.num1 + x.num2
        _ = y.no1 + y.no2
    }
}


let a = sum(num1: 100, num2: 200)
print("Sum 模块内:\( a.num1, a.num2)")


let b = diff(no1: 200, no2: 100)
print("Diff 模块内: \(b.no1, b.no2)")

The execution output of the above program is:

mult 模块内 (100, 200)
mult 模块内 (200, 100)
mult 模块内 (300, 500)
mult 模块内 (300, 100)
Sum 模块内:(100, 200)
Diff 模块内: (200, 100)

Method

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

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

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

4.topics({
   print("扩展模块内")       
})    
    
3.topics({
   print("内型转换模块内")       
})

The execution output of the above program is:

扩展模块内
扩展模块内
扩展模块内
扩展模块内
内型转换模块内
内型转换模块内
内型转换模块内

ThistopicsThe method uses a single parameter of type () -> (), indicating that the function has no parameters and no return value.

After defining this extension, you can call the topics method on any integer, and the function is to execute a task multiple times:


Variable instance Method

Instance methods added by extension can also modify the instance itself.

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

Example

The following example adds a new modification method named square to Swift's Double type to implement the square calculation of a primitive value:

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

var Trial1 = 3.3
Trial1.square()
print("圆的面积为: \(Trial1)")


var Trial2 = 5.8
Trial2.square()
print("圆的面积为: \(Trial2)")


var Trial3 = 120.3
Trial3.square()
print("圆的面积为: \(Trial3)")

Above The output result of program execution is:

圆的面积为: 34.210935
圆的面积为: 105.68006
圆的面积为: 45464.070735

Subscript

Extension can add a new subscript to an existing type.

Example

The following example adds an integer subscript to the Swift built-in type Int. The subscript [n] returns a decimal number

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 above program execution output result is:

2
6
5

Nested type

Extensions can be made to existing classes, Add new nested types to 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 result of the execution of the above program is:

 10 
 20 
 30 
 40 
 50 
 50