Swift - 扩展

  • 简述

    可以在扩展的帮助下添加现有类、结构或枚举类型的功能。类型功能可以通过扩展添加,但扩展无法覆盖功能。
    Swift Extension Functionalities
    • 添加计算属性和计算类型属性
    • 定义实例和类型方法。
    • 提供新的初始化程序。
    • 定义下标
    • 定义和使用新的嵌套类型
    • 使现有类型符合协议
    扩展是用关键字“extension”声明的

    句法

    
    extension SomeType {
       // new functionality can be added here
    }
    
    现有的类型也可以通过扩展来使其成为协议标准,其语法类似于类或结构的语法。
    
    extension SomeType: SomeProtocol, AnotherProtocol {
       // protocol requirements is described here
    }
    
  • 计算属性

    计算的“实例”和“类型”属性也可以在扩展的帮助下进行扩展。
    
    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)")
    
    当我们使用playground运行上述程序时,我们得到以下结果 -
    
    Addition is 103
    Subtraction is 110
    Multiplication is 390
    Division is 11
    Mixed Type is 154
    
  • 初始化程序

    Swift 4 提供了通过扩展向现有类型添加新初始化器的灵活性。用户可以添加自己的自定义类型来扩展已经定义的类型,并且还可以使用其他初始化选项。扩展仅支持 init()。扩展不支持 deinit()。
    
    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)")
    
    当我们使用playground运行上述程序时,我们得到以下结果 -
    
    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 Int {
       func topics(summation: () -> ()) {
          for _ in 0..<self {
             summation()
          }
       }
    }
    4.topics(summation: {
       print("Inside Extensions Block")
    })
    3.topics(summation: {
       print("Inside Type Casting Block")
    })
    
    当我们使用playground运行上述程序时,我们得到以下结果 -
    
    Inside Extensions Block
    Inside Extensions Block
    Inside Extensions Block
    Inside Extensions Block
    Inside Type Casting Block
    Inside Type Casting Block
    Inside Type Casting Block
    
    topic() 函数接受类型为 '(summation: () → ())' 的参数来表示该函数不接受任何参数并且不会返回任何值。要多次调用该函数,请初始化 for 块并初始化对带有 topic() 的方法的调用。
  • 变异实例方法

    当声明为扩展时,实例方法也可以改变。
    修改 self 或其属性的结构和枚举方法必须将实例方法标记为变异,就像从原始实现中变异方法一样。
    
    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)")
    
    当我们使用playground运行上述程序时,我们得到以下结果 -
    
    Area of circle is: 34.210935
    Area of circle is: 105.68006
    Area of circle is: 45464.070735
    
  • 下标

    使用扩展也可以向已经声明的实例添加新的下标。
    
    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])
    
    当我们使用playground运行上述程序时,我们得到以下结果 -
    
    2
    6
    5
    
  • 嵌套类型

    类、结构和枚举实例的嵌套类型也可以在扩展的帮助下进行扩展。
    
    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])
    
    当我们使用playground运行上述程序时,我们得到以下结果 -
    
    10
    20
    30
    40
    50
    50