Swift - rozszerzenia
Funkcjonalność istniejącej klasy, struktury lub typu wyliczenia można dodać za pomocą rozszerzeń. Funkcję typu można dodać za pomocą rozszerzeń, ale zastąpienie funkcji nie jest możliwe w przypadku rozszerzeń.
Swift Extension Functionalities -
- Dodawanie obliczonych właściwości i obliczonych właściwości typu
- Definiowanie metod instancji i typów.
- Udostępnianie nowych inicjatorów.
- Definiowanie indeksów
- Definiowanie i używanie nowych typów zagnieżdżonych
- Dostosowanie istniejącego typu do protokołu
Rozszerzenia są deklarowane ze słowem kluczowym „rozszerzenie”
Składnia
extension SomeType {
// new functionality can be added here
}
Istniejący typ można również dodać z rozszerzeniami, aby stał się standardem protokołu, a jego składnia jest podobna do klas lub struktur.
extension SomeType: SomeProtocol, AnotherProtocol {
// protocol requirements is described here
}
Obliczone właściwości
Obliczone właściwości „instancji” i „typu” można również rozszerzyć za pomocą rozszerzeń.
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)")
Gdy uruchomimy powyższy program za pomocą placu zabaw, otrzymamy następujący wynik -
Addition is 103
Subtraction is 110
Multiplication is 390
Division is 11
Mixed Type is 154
Inicjatory
Swift 4 zapewnia elastyczność dodawania nowych inicjatorów do istniejącego typu za pomocą rozszerzeń. Użytkownik może dodawać własne typy niestandardowe, aby rozszerzyć typy już zdefiniowane, a także dodatkowe opcje inicjalizacji. Rozszerzenia obsługują tylko init (). Funkcja deinit () nie jest obsługiwana przez rozszerzenia.
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)")
Gdy uruchomimy powyższy program za pomocą placu zabaw, otrzymamy następujący wynik -
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)
Metody
Nowe metody instancji i metody typów można dodać dalej do podklasy za pomocą rozszerzeń.
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")
})
Gdy uruchomimy powyższy program za pomocą placu zabaw, otrzymamy następujący wynik -
Inside Extensions Block
Inside Extensions Block
Inside Extensions Block
Inside Extensions Block
Inside Type Casting Block
Inside Type Casting Block
Inside Type Casting Block
Funkcja topics () przyjmuje argument typu '(sumowanie: () → ())', aby wskazać, że funkcja nie przyjmuje żadnych argumentów i nie zwróci żadnych wartości. Aby wywołać tę funkcję wiele razy, inicjowany jest blok for, a wywołanie metody z topic () jest inicjowane.
Metody mutacji instancji
Metody instancji można również mutować, gdy są zadeklarowane jako rozszerzenia.
Struktury i metody wyliczania, które modyfikują self lub jego właściwości, muszą oznaczać metodę instancji jako mutującą, podobnie jak mutowanie metod z oryginalnej implementacji.
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)")
Gdy uruchomimy powyższy program za pomocą placu zabaw, otrzymamy następujący wynik -
Area of circle is: 34.210935
Area of circle is: 105.68006
Area of circle is: 45464.070735
Indeksy
Dodanie nowych indeksów do już zadeklarowanych instancji jest również możliwe dzięki rozszerzeniom.
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])
Gdy uruchomimy powyższy program za pomocą placu zabaw, otrzymamy następujący wynik -
2
6
5
Zagnieżdżone typy
Zagnieżdżone typy dla instancji klas, struktur i wyliczeń można również rozszerzyć za pomocą rozszerzeń.
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])
Gdy uruchomimy powyższy program za pomocą placu zabaw, otrzymamy następujący wynik -
10
20
30
40
50
50