funkcjonalny Swift: zamknięcia { }

podziękowania: Pexels

zamknięcia to samodzielne bloki funkcjonalności, które mogą być przekazywane i używane w kodzie.

— Apple

Closures może przechwytywać i przechowywać odwołania do dowolnych stałych i zmiennych z kontekstu, w którym są zdefiniowane, znane jako closing over stay Closure. Możesz myśleć o zamknięciu jako o funkcji, która nie ma własnej nazwy i przechwytuje jakiekolwiek wartości z otoczenia. Funkcje i zamknięcia są obiektami pierwszej klasy w języku Swift: możesz je przechowywać, przekazywać jako argumenty do funkcji i traktować je tak, jak każdą inną wartość lub obiekt. Przekazywanie zamknięć jako procedur obsługi zakończenia jest częstym wzorem w wielu interfejsach API. Standardowa biblioteka Swift używa zamknięć głównie do obsługi zdarzeń i wywołań zwrotnych.

funkcje są samodzielnymi kawałkami kodu, które wykonują określone zadanie. Nadajesz funkcji nazwę, która identyfikuje to, co robi, i ta nazwa jest używana do „wywołania” funkcji, aby wykonać jej zadanie w razie potrzeby. Definiujesz funkcję za pomocą słowa kluczowego func. Funkcje mogą przyjmować none do wielu parametrów, zmiennych parametrów i zwracać none lub wiele parametrów.

funkcja przyjmuje 2 paramy i zwraca 1 param

typy funkcji

Typ funkcji składa się z typów parametrów i typu zwracanego funkcji. Dla powyższego przykładu, typ funkcji to:(Int, Int) -> Int

można to odczytać jako: „funkcja, która ma dwa parametry, oba typu Int i która zwraca wartość typu Int.”Typ funkcji można ustawić jako parametr lub zwracać typ funkcji.

typy funkcji można przypisać do dowolnej zmiennej w ten sposób:

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

funkcje są szczególnymi przypadkami zamknięcia. Zamknięcia przyjmują jedną z trzech form:

  • funkcje globalne: mają nazwę i nie mogą przechwytywać wartości.
  • funkcje zagnieżdżone: mają nazwę i mogą przechwytywać wartości z funkcji załączającej.
  • wyrażenia zamknięcia: nie mają nazwy i mogą przechwytywać wartości z otaczającego ich kontekstu.

:

szybkie zamknięcie dokumentu

Zamknięcie można utworzyć, umieszczając typ funkcji wewnątrz nawiasów klamrowych i in słowo kluczowe po typie zwrotnym.

skrócone nazwy argumentów

argumenty zamykające mogą odnosić się do pozycji, np. , , , i tak dalej.

po określeniu skróconych nazw nie ma potrzeby podawania argumentów zamknięcia i w słowie kluczowym

niejawne Zwroty Z Zamknięcia:

jednokrotne zamknięcia mogą domyślnie zwracać wynik swojego pojedynczego wyrażenia, pomijając słowo kluczowe return w swojej deklaracji.

w przypadku zamknięcia wyrażenia wielowierszowego nie można pominąć słowa kluczowego return.

:

jeśli chcesz przekazać wyrażenie zamknięcia funkcji jako ostatni argument funkcji, a wyrażenie zamknięcia jest zbyt długie, można je zapisać jako końcowe zamknięcie. Końcowe zamknięcie jest zapisywane po nawiasach wywołania funkcji (), mimo że nadal jest argumentem funkcji. Kiedy używasz składni zamknięcia końcowego, nie zapisujesz etykiety argumentu zamknięcia jako części wywołania funkcji.

Zamknięcie jako argument wywołania metody

Zamknięcie końcowe (tj. zamknięcie Po nawiasach metody)

jeśli zamknięcie jest ostatnim parametrem metody, to swift pozwala na zapisanie w ten sposób 🖕

przykład zamknięcia za pomocą reduce()

użycie końcowej składni zamknięcia starannie hermetyzuje funkcjonalność zamknięcia bezpośrednio po funkcji obsługiwanej przez closure, bez konieczności zawijania całego zamknięcia w zewnętrzne nawiasy metody reduce(_:).

Przechwytywanie wartości:

zamknięcie może przechwytywać stałe i zmienne z otaczającego kontekstu, w którym jest zdefiniowane. Zamknięcie może następnie odwoływać się i modyfikować wartości tych stałych i zmiennych z jego ciała, nawet jeśli pierwotny zakres, który zdefiniował stałe i zmienne, już nie istnieje.

w języku Swift najprostszą formą zamknięcia, która może przechwytywać wartości, jest funkcja zagnieżdżona, zapisana w ciele innej funkcji. Funkcja zagnieżdżona może przechwytywać dowolne argumenty swojej funkcji zewnętrznej, a także może przechwytywać dowolne stałe i zmienne zdefiniowane w funkcji zewnętrznej.

przykład podany w dokumencie Swift

ta makeIncrementerfunkcja przyjmuje jeden argument tj. Int jako wejście i zwraca typ funkcji tj. () -> Int. Oznacza to, że zwraca funkcję, a nie prostą wartość. Funkcja, którą zwraca, nie ma parametrów i za każdym razem zwraca wartość Int.

tutaj amount jest argumentem, runningTotal jest zadeklarowana jako zmienna i zainicjalizowana za pomocą 0. Zagnieżdżona funkcja incrementer przechwytuje amount i runningTotal z otaczającego kontekstu.

zobaczmy makeIncrementer w akcji:

Uwaga: Jako optymalizacja, Swift może zamiast tego przechwytywać i przechowywać kopię wartości, jeśli ta wartość nie jest zmutowana przez zamknięcie i jeśli nie jest zmutowana po utworzeniu zamknięcia.

Swift obsługuje również wszystkie zarządzanie pamięcią związane z usuwaniem zmiennych, gdy nie są już potrzebne.

aby pozbyć się długiego wyrażenia zamknięcia w argumencie funkcji, możesz użyć typealias.

Nieujawniające się zamknięcia:

parametry zamknięcia były domyślnie wyłączone przed Swift 3. Zamknięcie nie ucieknie przed ciałem funkcji, jeśli parametry zamknięcia są oznaczone jako nie-uciekające

w Swift 3 zostało odwrócone. Kiedy przekazujesz closure jako argument funkcji, closure zostaje wykonane z ciałem funkcji i zwraca kompilator z powrotem. Gdy wykonanie się kończy, przekazane zamknięcie wychodzi poza zakres i nie ma już istnienia w pamięci.

najmniej, co musisz wiedzieć

parametry zamknięcia domyślnie nie są escaping, jeśli chcesz uciec przed wykonaniem zamknięcia, musisz użyć @escaping z parametrami zamknięcia.

1. Przekaż zamknięcie jako argument funkcji podczas wywołania funkcji.
2. Wykonaj pewną pracę w funkcji, a następnie wykonaj zamknięcie.
3. Funkcja zwraca.

ze względu na lepsze zarządzanie pamięcią i optymalizacje, Swift zmienił wszystkie zamknięcia, aby domyślnie nie uciekały. CaptureList.swift jest przykładem zamknięcia nieinwazyjnego.

Uwaga :adnotacja @ non-escaping dotyczy tylko typów funkcji

Escaping Closures:

mówi się, że zamknięcie powoduje wyjście funkcji, gdy zamknięcie jest przekazywane jako argument do funkcji, ale jest wywoływane po powrocie funkcji. Oznaczanie zamknięcia za pomocą @escaping oznacza, że musisz wyraźnie odwołać się do self w obrębie zamknięcia.

1. Przekaż zamknięcie jako argument funkcji podczas wywołania funkcji.
2. Wykonaj dodatkową pracę w funkcji.
3. Funkcja wykonuje zamknięcie asynchronicznie lub zapisuje.
4. Funkcja zwraca.

zobaczmy, gdzie domyślnie są zamykane:

  • zmienne typu funkcji są niejawnymi ucieczkami
  • typealiazy są niejawnymi ucieczkami
  • opcjonalne zamknięcia są niejawnymi ucieczkami

wspólny błąd:

Przypisywanie nie-uciekającego zamknięcia do zamykania ucieczki. Istnieją 2 sposoby, aby to naprawić:

  • Oznacz zamknięcie jako wyjście ewakuacyjne
  • lub zachowaj domyślne zachowanie @noescape, czyniąc zamknięcie opcjonalnym

Autoklosures:

atrybut Swift @autoclosure umożliwia zdefiniowanie argumentu, który zostanie automatycznie zawinięty w Zamknięcie. Nie przyjmuje żadnych argumentów, a kiedy jest wywoływany, Zwraca wartość wyrażenia, które jest wewnątrz niego zawinięte. Ta wygoda składniowa pozwala pominąć nawiasy klamrowe wokół parametru funkcji, pisząc zwykłe wyrażenie zamiast jawnego zamknięcia.

na przykład funkcja assert(condition:message:file:line:) pobiera autoklosure dla swoich parametrów condition i message; jej parametr condition jest obliczany tylko w kompilacjach debugowania, a jej parametr message jest obliczany tylko wtedy, gdy conditionjest false.

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

aby użyć @autoclosure z @escaping składnia atrybutów jest:

@autoclosure @escaping () -> Bool

zamknięcia vs bloki:

„szybkie zamykanie i bloki Objective-C są kompatybilne, więc możesz przekazywać szybkie zamykanie do metod Objective-C, które oczekują bloków. Szybkie zamknięcia i funkcje mają ten sam typ, dzięki czemu można nawet przekazać nazwę funkcji Swift. Zamknięcia mają podobną semantykę przechwytywania jak bloki, ale różnią się w jeden kluczowy sposób: zmienne są raczej mutowalne niż kopiowane. Innymi słowy, zachowanie _ _ block w Objective-C jest domyślnym zachowaniem zmiennych w Swift.”

rozwiązanie zależy od problemu. Co więcej, Apple przesuwa swój nacisk na wzorzec wywołania zwrotnego. UIAlertAction jest tego przykładem.

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

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.

Previous post Thoughts on Horse Barn Heaters-Blackburn Architects, P. C.: Blackburn Architects, P. C.
Next post gwarancja