Funcional Swift: Encerramentos { }

Desmistificando @escapar, @não escapar, @autoclosure e curry função

Aaina jain
Aaina jain

Siga

27 de Junho de 2018 · 7 min de leitura

Créditos: Pexels

os Fechamentos são auto-contidos blocos de funcionalidade que pode ser passado em volta e utilizados em seu código.

— Apple

Closures can capture and store references to any constants and variables from the context in which they are defined, known as closing over hence Closure. Você pode pensar em um fechamento como sendo uma função que não tem um nome próprio e captura quaisquer valores de seu ambiente. Funções e fechamentos são objetos de primeira classe no Swift: você pode armazená-los, passá-los como argumentos para funções, e tratá-los como você faria qualquer outro valor ou objeto. Passar fechamentos como tratadores de acabamento é um padrão comum em muitas APIs. A Standard Swift library usa fechamentos principalmente para movimentação de eventos e callbacks.

funções são blocos de código auto-suficientes que executam uma tarefa específica. Você dá a uma função um nome que identifica o que ela faz, e este nome é usado para “chamar” a função para executar sua tarefa quando necessário. Você define uma função com a palavra-chave func. Funções não podem levar nenhum a muitos parâmetros, parâmetros variádicos e retornar nenhum ou vários parâmetros.

a Função de levar de 2 parâmetros e retornar 1 param

Tipos de Função

tipo de Função é feita de tipos de parâmetros e o tipo de retorno da função. Por exemplo, o tipo de função é:(Int, Int) -> Int

isto pode ser lido como: “uma função que tem dois parâmetros, ambos do tipo Int e que retorna um valor do tipo Int.”Tipo de função pode ser definido como parâmetro ou tipo de retorno de função.

tipos de funções podem ser atribuídos a qualquer variável como esta:

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

funções são casos especiais de encerramento. Os encerramentos assumem uma de três formas::

  • funções globais: eles têm um nome e não podem capturar valor.
  • funções aninhadas: elas têm um nome e podem capturar valores de sua função envolvente.
  • expressões de encerramento: eles não têm nome e podem capturar valores de seu contexto circundante.Expressão De Encerramento:

    Swift Fechamento do Documento

    Fechamento pode ser criado, colocando um tipo de função dentro de chavetas e in palavra-chave, depois de o tipo de retorno.

    os argumentos Estenográficos podem se referir a uma posição. , , , e assim por diante.

    Depois de especificar abreviada de nomes não é necessário especificar o encerramento argumentos e na palavra-chave

    Implícito Retorna de Encerramento:

    Único-expressão fechamentos implicitamente pode retornar o resultado de sua única expressão, omitindo a return palavra-chave de sua declaração.

    Para uma de várias linhas de expressão encerramento, return palavra-chave não pode ser omitido.

    Encerramento Posterior:

    se você precisar passar uma expressão de fechamento para uma função como o último argumento da função e a expressão de fechamento é muito longa, ela pode ser escrita como fechamento posterior. Um fechamento posterior é escrito após os parênteses da chamada de função (), mesmo que ainda seja um argumento para a função. Quando você usa a sintaxe de encerramento posterior, você não escreve o rótulo de argumento para o encerramento como parte da chamada de função.

    o Fechamento como um argumento para o método de chamada

    À direita Encerramento (i.e. fechamento após o método parênteses)

    Se o fechamento é o último parâmetro de um método, em seguida, swift permite escrever assim 🖕

    à Direita encerramento reduzir o()

    A utilização de final de fechamento de sintaxe ordenadamente encapsula o encerramento da funcionalidade imediatamente após a função que o fechamento de suporte, sem a necessidade de moldar todo o fechamento dentro de reduce(_:) método do exterior parênteses.

    valores de captura:

    um fecho pode capturar constantes e variáveis do contexto circundante no qual é definido. O fechamento pode então se referir e modificar os valores dessas constantes e variáveis de dentro de seu corpo, mesmo que o escopo original que definiu as constantes e variáveis não exista mais.

    in Swift, the simplest form of a closure that can capture values is a nested function, written within the body of another function. Uma função aninhada pode capturar qualquer dos argumentos de sua função externa e também pode capturar quaisquer constantes e variáveis definidas dentro da função externa.

    exemplo dado no documento Swift

    esta função makeIncrementer aceita um argumento, ou seja, Int como input e devolve um tipo de função, ou seja () -> Int. Isto significa que retorna uma função, ao invés de um valor simples. A função que retorna não tem parâmetros, e retorna um valor Int cada vez que é chamado.

    aqui amount é argumento, runningTotal é declarado como variável e inicializado com 0. Função aninhada incrementer captura amount e runningTotal do contexto circundante.

    vejamos makeIncrementer em acção:

    Nota: Como uma otimização, Swift pode capturar e armazenar uma cópia de um valor se esse valor não for modificado por um fechamento, e se o valor não for modificado após o fechamento ser criado.

    Swift também lida com toda a gestão de memória envolvida na eliminação de variáveis quando elas já não são necessárias.

    para se livrar da expressão de fechamento longo no argumento de função você pode usar typealias.

    os parâmetros de encerramento estavam escapando por padrão antes do Swift 3. Um fechamento não escaparia do corpo da função se os parâmetros de fechamento são marcados como não escapando

    no Swift 3 foi revertido. Quando você está passando um fechamento como o argumento da função, o fechamento é executado com o corpo da função e retorna o compilador de volta. À medida que a execução termina, o fechamento passado sai do escopo e não tem mais existência na memória.

    o mínimo que precisa de saber é que os parâmetros de Fecho não estão a escapar por omissão, se quiser escapar à execução de Fecho, terá de usar o @escaping com os parâmetros de Fecho.

    Lifecycle of the non-escaping closure:
    1. Passar o fechamento como um argumento de função, durante a chamada de função.
    2. Faça algum trabalho em função e depois execute o encerramento.
    3. A função retorna.

    devido a uma melhor gestão de memória e otimizações, a Swift mudou todos os encerramentos para não escapar por padrão. CaptureList.swift é um exemplo de fechamento não-escapatória.

    Nota: @anotação sem Escape aplica-se apenas aos tipos de funções

    dispositivos de escape:

    um fecho é dito para escapar de uma função quando o fecho é passado como um argumento para a função, mas é chamado após a função retorna. Marcar um fecho com @escaping significa que você tem que se referir a self explicitamente dentro do fecho.

    ciclo de vida do fecho @escaping:
    1. Passar o fechamento como argumento de função, durante a chamada de função.
    2. Faça algum trabalho adicional na função.
    3. Função executar o fecho assíncronamente ou armazenado.
    4. A função retorna.

    vamos ver onde os encerramentos estão por omissão a escapar:

    • Variáveis de tipo de função estão implícitos escapar
    • typealiases estão implícitos escapar
    • Opcional vedantes estão implícitos escapar

    Erro Comum:

    a Atribuição de não sair de encerramento para escapar de encerramento. Existem 2 maneiras de corrigir isso:

    • Marca encerramento escapar
    • Ou mantenha o padrão @noescape comportamento, fazendo o fechamento opcional

    Autoclosures:

    Swift @autoclosure atributo permite que você defina um argumento que automaticamente fica envolto em um fechamento. Não é preciso argumentos, e quando é chamado, ele retorna o valor da expressão que está embrulhada dentro dele. Esta conveniência sintática permite que você omita Chavetas em torno do parâmetro de uma função, escrevendo uma expressão normal em vez de um fechamento explícito.

    por exemplo, a função assert(condition:message:file:line:) toma um autoclosure para os seus parâmetros condition e message; o seu parâmetro condition é avaliado apenas em compilações de depuração e o seu parâmetro message é avaliado apenas se conditionfor false.

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

    to use @autoclosure with @escaping attribute syntax is:

    @autoclosure @escaping () -> Bool

    fechos vs blocos:

    ” Swift clasures and Objective-C blocks are compatible so you can pass Swift clasures to Objective-C methods that expect blocks. Fechamentos Swift e funções têm o mesmo tipo para que você possa até passar o nome de uma função Swift. Os encerramentos têm semântica de captura semelhante aos blocos, mas diferem de uma maneira chave: as variáveis são mutáveis ao invés de copiadas. Em outras palavras, o comportamento de __bloco no Objective-C é o comportamento padrão para variáveis no Swift.”

    Encerramentos vs delegados:

    a solução depende do problema. Além disso, a Apple está mudando seu foco para Padrão de Callback. UIAlertAction é um exemplo disso.

    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

Deixe uma resposta

O seu endereço de email não será publicado.

Previous post Thoughts on Horse Barn Aquers-Blackburn Architects, P. C.: Blackburn Architects, P. C.
Next post garantia