Mis on sulgemine?
sobes.tech AI
Vastus AI-lt
Sulgemine (closure) Swiftis on iseseisev funktsionaalsuse plokk ({}), mida saab koodis edasi anda ja kasutada. Sulgemised võivad haarata ja salvestada viiteid mis tahes konstantidele ja muutujatele kontekstist, kus need on määratletud.
Kasutamise näited:
- Funktsioonide argumentidena (näiteks Completion Handlers).
- Kolektsioonide käitumise määratlemiseks iteratsiooni ajal (näiteks kasutades meetodeid
map,filter,reduce,sorted). - Koodi hilisemaks täitmiseks.
Süntaks:
// Põhisüntaks
{ (parameetrid) -> tagastatüüp in
laused
}
// Näide sulgemisest, mis võtab vastu Int ja tagastab String
let integerToString: (Int) -> String = { (number: Int) -> String in
return "Number: \(number)"
}
Omadused:
- Muutujate automaatne haaramine (capturing values).
- Võimalus määratleda sulgemisi ilma otsese parameetrite ja tagastatüüpide määramiseta (süntaktiline suhkur).
- Lühendatud parameetrite nimede kasutamine ($0, $1 jne).
- Sulgemise süntaks (trailing closure syntax).
Muutujate haaramine:
Sulgemine võib haarata oma keskkonnast muutujad. Vaikimisi toimub haaramine viitega. Kui sulgemist kasutatakse pärast seda, kui algne muutuja on välja läinud, säilitab sulgemine endiselt juurdepääsu sellele.
func makeIncrementer(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0 // Väline muutuja
let incrementer: () -> Int = { // Sulgemine
runningTotal += amount // Haarab runningTotal ja amount
return runningTotal
}
return incrementer
}
let incrementByTen = makeIncrementer(forIncrement: 10)
print(incrementByTen()) // Väljund: 10
print(incrementByTen()) // Väljund: 20
Haaramise nimekirjad (Capture Lists):
Need võimaldavad selgelt määrata, kuidas muutujad haaratakse - väärtusena või viitega, ning vältida tugevaid viite tsükleid (retain cycles).
class MyClass {
var value = 0
lazy var myClosure: () -> Void = { [self, value] in // Haarab self viitega, value väärtusega
print("self.value väärtus: \(self.value)")
print("Haaratud väärtus: \(value)")
}
deinit {
print("MyClass eksemplar vabastatud")
}
}
Tugevate viite tsüklite vältimiseks haarates objekte klassidest, kasutatakse süntaksit [weak self] või [unowned self]:
class ViewController {
var dataFetcher: DataFetcher?
func fetchData() {
dataFetcher?.fetch { [weak self] result in // nõrk viide self-le
guard let self = self else { return } // kontroll, kas self eksisteerib
// tulemuse töötlemine
}
}
}
class DataFetcher {
var completionHandler: ((Result<String, Error>) -> Void)?
func fetch(completion: @escaping (Result<String, Error>) -> Void) {
self.completionHandler = completion
// Asünkroonne operatsioon...
}
}