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

Когда мы запускаем вышеуказанную программу с помощью игровой площадки, мы получаем следующий результат:

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

Когда мы запускаем вышеуказанную программу с помощью игровой площадки, мы получаем следующий результат:

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")
})

Когда мы запускаем вышеуказанную программу с помощью игровой площадки, мы получаем следующий результат:

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

Функция themes () принимает аргумент типа '(суммирование: () → ())', чтобы указать, что функция не принимает никаких аргументов и не возвращает никаких значений. Чтобы вызвать эту функцию несколько раз, инициализируется блок 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)")

Когда мы запускаем вышеуказанную программу с помощью игровой площадки, мы получаем следующий результат:

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

Когда мы запускаем вышеуказанную программу с помощью игровой площадки, мы получаем следующий результат:

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

Когда мы запускаем вышеуказанную программу с помощью игровой площадки, мы получаем следующий результат:

10
20
30
40
50
50