Swift funcțional: închideri { }

credite: Pexels

închiderile sunt blocuri de funcționalitate autonome care pot fi transmise și utilizate în codul dvs.

— Apple

închiderile pot capta și stoca referințe la orice constante și variabile din contextul în care sunt definite, cunoscute sub numele de închidere prin urmare închidere. Vă puteți gândi la o închidere ca fiind o funcție care nu are un nume propriu și captează orice valori din mediul său. Funcțiile și închiderile sunt obiecte de primă clasă în Swift: le puteți stoca, le puteți transmite ca argumente funcțiilor și le puteți trata ca orice altă valoare sau obiect. Trecerea închiderilor ca gestionari de finalizare este un model comun în multe API-uri. Biblioteca Swift standard folosește închideri mai ales pentru gestionarea evenimentelor și apeluri.

funcțiile sunt bucăți de cod autonome care îndeplinesc o sarcină specifică. Dați unei funcții un nume care identifică ceea ce face și acest nume este folosit pentru a „apela” funcția pentru a-și îndeplini sarcina atunci când este necesar. Definiți o funcție cu cuvântul cheie func. Funcțiile pot lua nici unul la mai mulți parametri, parametrii variadic și a reveni nici unul sau mai mulți parametri.

funcția ia 2 params și retur 1 param

tipuri de funcții

Tipul funcției este alcătuit din tipurile de parametri și tipul de retur al funcției. Pentru exemplul de mai sus, tipul funcției este:(Int, Int) -> Int

aceasta poate fi citită ca: „o funcție care are doi parametri, ambii de tip Int și care returnează o valoare de tip Int.”Tipul funcției poate fi setat ca parametru sau tip de retur al funcției.

tipurile de funcții pot fi atribuite oricărei variabile ca aceasta:

var mathFunction: (Int, Int) -> Int = add

funcțiile sunt cazuri speciale de închidere. Închiderile iau una din cele trei forme:

  • funcții globale: au un nume și nu pot capta valoare.
  • funcții imbricate: au un nume și pot capta valori din funcția lor de închidere.
  • expresii de închidere: nu au nume și pot capta valori din contextul înconjurător.

Expresie De Închidere:

documentul de închidere rapidă

Închiderea poate fi creată prin introducerea unui tip de funcție în interiorul acolade și in cuvânt cheie după tipul de retur.

numele argumentelor prescurtate

argumentele de închidere se pot referi la o poziție adică. , , , și așa mai departe.

după specificarea numelor prescurtate nu este nevoie să specificați argumente de închidere și în cuvinte cheie

returnări implicite de la închidere:

închiderile cu o singură expresie pot returna implicit rezultatul expresiei lor unice omițând cuvântul cheie return din declarația lor.

pentru o închidere Expresie multilinie, return cuvinte cheie nu pot fi omise.

Închidere Finală:

dacă trebuie să transmiteți o expresie de închidere unei funcții, deoarece ultimul argument al funcției și expresia de închidere este prea lungă, aceasta poate fi scrisă ca închidere finală. O închidere finală este scrisă după parantezele apelului funcției (), chiar dacă este încă un argument pentru funcție. Când utilizați sintaxa de închidere finală, nu scrieți eticheta argumentului pentru închidere ca parte a apelului de funcții.

închiderea ca argument pentru apelarea metodei

închidere finală (i. e. închiderea după parantezele metodei)

dacă închiderea este ultimul parametru al unei metode, atunci swift vă permite să scrieți astfel 🖕

exemplu de închidere finală utilizând reducerea()

utilizarea sintaxei de închidere finală încapsulează perfect funcționalitatea închiderii imediat după funcția pe care o acceptă închiderea, fără a fi nevoie să înfășurați întreaga închidere în parantezele exterioare ale metodei reduce(_:).

captarea valorilor:

o închidere poate capta constante și variabile din contextul înconjurător în care este definită. Închiderea se poate referi apoi la și modifica valorile acelor constante și variabile din interiorul corpului său, chiar dacă domeniul inițial care a definit constantele și variabilele nu mai există.

în Swift, cea mai simplă formă de închidere care poate capta valori este o funcție imbricată, scrisă în corpul unei alte funcții. O funcție imbricată poate capta oricare dintre argumentele funcției sale exterioare și poate capta, de asemenea, orice constante și variabile definite în cadrul funcției exterioare.

exemplu dat în documentul Swift

această funcție makeIncrementer acceptă un argument și anume Int ca intrare și returnează un tip de funcție, adică () -> Int. Aceasta înseamnă că returnează o funcție, mai degrabă decât o valoare simplă. Funcția pe care o returnează nu are parametri și returnează o valoare Int de fiecare dată când este apelată.

aici amount este argument, runningTotal este declarat ca variabilă și inițializat cu 0. Funcția imbricată incrementer captează amount și runningTotal din contextul înconjurător.

să vedem makeIncrementer în acțiune:

notă: Ca optimizare, Swift poate captura și stoca o copie a unei valori dacă acea valoare nu este mutată de o închidere și dacă valoarea nu este mutată după crearea închiderii.

Swift gestionează, de asemenea, toate gestionarea memoriei implicate în eliminarea variabilelor atunci când acestea nu mai sunt necesare.

pentru a scăpa de expresia de închidere lungă în Argumentul funcției, puteți utiliza typealias.

închideri care nu scapă:

parametrii de închidere scăpau în mod implicit înainte de Swift 3. O închidere nu ar scăpa de corpul funcției dacă parametrii de închidere sunt marcați ca

care nu scapă în Swift 3 a fost inversat. Când treceți o închidere ca argument al funcției, închiderea se execută cu corpul funcției și returnează compilatorul înapoi. Pe măsură ce execuția se termină, închiderea trecută iese din sfera de aplicare și nu mai există în memorie.

cel mai puțin trebuie să știți

parametrii de închidere nu scapă în mod implicit, dacă doriți să scăpați de execuția de închidere, trebuie să utilizați @escaping cu parametrii de închidere.

ciclul de viață al închiderii care nu scapă:
1. Treceți închiderea ca argument funcțional, în timpul apelului de funcții.
2. Faceți unele lucrări în funcție și apoi executați închiderea.
3. Funcția se întoarce.

datorită unei mai bune gestionări și optimizări a memoriei, Swift a schimbat toate închiderile pentru a nu scăpa în mod implicit. CaptureList.swift este un exemplu de închidere care nu scapă.

notă: @ adnotarea care nu scapă se aplică numai tipurilor de funcții

închideri care scapă:

se spune că o închidere scapă unei funcții atunci când închiderea este transmisă ca argument funcției, dar este apelată după ce funcția revine. Marcarea unei închideri cu @escaping înseamnă că trebuie să vă referiți la self în mod explicit în cadrul închiderii.

ciclul de viață al închiderii @escaping:
1. Treceți închiderea ca argument de funcție, în timpul apelului de funcție.
2. Faceți unele lucrări suplimentare în funcție.
3. Funcție executați închiderea asincronă sau stocată.
4. Funcția se întoarce.

să vedem unde se închid în mod implicit:

  • variabilele tipului de funcție sunt implicite care scapă
  • tipealiazele sunt implicite care scapă
  • închiderile opționale sunt implicite care scapă

eroare comună:

atribuirea închiderii care nu scapă închiderii care scapă. Există 2 moduri de a remedia acest lucru:

  • marcați închiderea ca scăpând
  • sau păstrați comportamentul @noescape implicit făcând închiderea opțională

Autoclosures:

atributul Swift @autoclosure vă permite să definiți un argument care se înfășoară automat într-o închidere. Ea nu ia nici un argument, și atunci când este numit, returnează valoarea expresiei care este înfășurat în interiorul ei. Această comoditate sintactică vă permite să omiteți bretele în jurul parametrului unei funcții scriind o expresie normală în loc de o închidere explicită.

de exemplu, funcția assert(condition:message:file:line:) ia o autoclosură pentru parametrii săi condition și message; parametrul său condition este evaluat numai în compilările de depanare și parametrul său message este evaluat numai dacă conditioneste false.

func assert(_ expression: @autoclosure () -> Bool,
_ message: @autoclosure () -> String) {}

pentru a utiliza @autoclosure cu @escaping sintaxa atributului este:

@autoclosure @escaping () -> Bool

închideri vs blocuri:

„închiderile Swift și blocurile Objective-C sunt compatibile, astfel încât să puteți trece închiderile Swift la metodele Objective-C care se așteaptă la blocuri. Închiderile și funcțiile Swift au același tip, astfel încât să puteți trece chiar și numele unei funcții Swift. Închiderile au semantică de captare similară cu blocurile, dar diferă într-un mod cheie: variabilele sunt mutabile mai degrabă decât copiate. Cu alte cuvinte, comportamentul __block în Objective-C este comportamentul implicit pentru variabilele din Swift.”

închideri vs delegați:

soluția depinde de problemă. Mai mult, Apple își schimbă accentul pe modelul de apel invers. UIAlertAction este un exemplu în acest sens.

https://medium.com/@abhimuralidharan/functional-swift-all-about-closures-310bc8af31dd

https://medium.com/@kumarpramod017/what-do-mean-escaping-and-nonescaping-closures-in-swift-d404d721f39d

https://oleb.net/blog/2016/10/optional-non-escaping-closures/

https://swiftunboxed.com/lang/closures-escaping-noescape-swift3/

https://medium.com/@johnsundell/using-autoclosure-when-designing-swift-apis-67fe20a8b2e

Lasă un răspuns

Adresa ta de email nu va fi publicată.

Previous post Gânduri pe horse Barn Incalzitoare – Blackburn Architects, P. C.: Blackburn Architects, P. C.
Next post garanție