Swift - fechamentos

Fechamentos em Swift 4 são semelhantes àqueles de funções independentes organizadas como blocos e chamadas em qualquer lugar, como as linguagens C e Objective C. Constantes e referências de variáveis ​​definidas dentro das funções são capturadas e armazenadas em fechamentos. As funções são consideradas como casos especiais de encerramentos e assumem as seguintes três formas -

Funções Globais Funções Aninhadas Expressões de fechamento
Tenha um nome. Não capture nenhum valor Tenha um nome. Capture valores da função envolvente Os fechamentos sem nome capturam valores dos blocos adjacentes

As expressões de fechamento na linguagem Swift 4 seguem estilos de sintaxe nítidos, otimizados e leves que incluem.

  • Inferindo tipo de parâmetro e valor de retorno do contexto.
  • Retornos implícitos de encerramentos de expressão única.
  • Nomes de argumentos abreviados e
  • Sintaxe de encerramento final

Sintaxe

A seguir está uma sintaxe genérica para definir o fechamento que aceita parâmetros e retorna um tipo de dados -

{
   (parameters) −> return type in
   statements
}

A seguir está um exemplo simples -

let studname = { print("Welcome to Swift Closures") }
studname()

Quando executamos o programa acima usando playground, obtemos o seguinte resultado -

Welcome to Swift Closures

O encerramento a seguir aceita dois parâmetros e retorna um valor Bool -

{     
   (Int, Int) −> Bool in
   Statement1
   Statement 2
   ---
   Statement n
}

A seguir está um exemplo simples -

let divide = {
   (val1: Int, val2: Int) -> Int in 
   return val1 / val2 
}

let result = divide(200, 20)
print (result)

Quando executamos o programa acima usando playground, obtemos o seguinte resultado -

10

Expressões em fechamentos

As funções aninhadas fornecem uma maneira conveniente de nomear e definir blocos de código. Em vez de representar toda a declaração de função e as construções de nome são usadas para denotar funções mais curtas. A representação da função em uma declaração breve e clara com sintaxe focada é obtida por meio de expressões de encerramento.

Programa de Ordem Ascendente

A classificação de uma string é realizada pela função reservada da tecla Swift 4s "classificada", que já está disponível na biblioteca padrão. A função classificará as strings fornecidas em ordem crescente e retornará os elementos em uma nova matriz com o mesmo tamanho e tipo de dados mencionados na matriz antiga. A antiga matriz permanece a mesma.

Dois argumentos são representados dentro da função classificada -

  • Valores de tipo conhecido representados como matrizes.

  • Conteúdo da matriz (Int, Int) e retorna um valor booleano (Bool) se a matriz for classificada corretamente, retornará o valor verdadeiro, caso contrário, retornará falso.

Uma função normal com string de entrada é escrita e passada para a função classificada para obter as strings classificadas para um novo array que é mostrado abaixo -

func ascend(s1: String, s2: String) -> Bool {
   return s1 > s2
}

let stringcmp = ascend(s1: "Swift 4", s2: "great")
print (stringcmp)

Quando executamos o programa acima usando playground, obtemos o seguinte resultado -

true

A matriz inicial a ser classificada para sorvete é fornecida como "Swift 4" e "ótimo". A função para classificar o array é declarada como tipo de dados string e seu tipo de retorno é mencionado como Booleano. Ambas as strings são comparadas e classificadas em ordem crescente e armazenadas em uma nova matriz. Se a classificação for realizada com sucesso, a função retornará um valor verdadeiro, caso contrário, retornará falso.

A sintaxe da expressão de fechamento usa -

  • parâmetros constantes,
  • parâmetros variáveis, e
  • parâmetros inout.

A expressão de fechamento não oferece suporte a valores padrão. Parâmetros variáveis ​​e tuplas também podem ser usados ​​como tipos de parâmetro e tipos de retorno.

let sum = {
   (no1: Int, no2: Int) -> Int in 
   return no1 + no2 
}

let digits = sum(10, 20)
print(digits)

Quando executamos o programa acima usando playground, obtemos o seguinte resultado -

30

Os parâmetros e declarações de tipo de retorno mencionados na instrução da função também podem ser representados pela função de expressão de fechamento embutida com a palavra-chave 'in'. Depois de declarar o parâmetro e o retorno, a palavra-chave 'in' é usada para denotar que o corpo da closure.

Retornos implícitos de expressão única

Aqui, o tipo de função do segundo argumento da função classificada deixa claro que um valor Bool deve ser retornado pelo encerramento. Como o corpo da closure contém uma única expressão (s1> s2) que retorna um valor Bool, não há ambigüidade e a palavra-chave return pode ser omitida.

Para retornar uma instrução de expressão única em fechamentos de expressão, a palavra-chave 'return' é omitida em sua parte de declaração.

var count:[Int] = [5, 10, -6, 75, 20]
let descending = count.sorted(by: { n1, n2 in n1 > n2 })
let ascending = count.sorted(by: { n1, n2 in n1 < n2 })

print(descending)
print(ascending)

Quando executamos o programa acima usando playground, obtemos o seguinte resultado -

[75, 20, 10, 5, -6]
[-6, 5, 10, 20, 75]

A própria instrução define claramente que quando a string1 é maior que a string 2 retorna verdadeiro, caso contrário, a instrução return é omitida aqui.

Fechamentos de tipo conhecido

Considere a adição de dois números. Sabemos que a adição retornará o tipo de dados inteiro. Portanto, os fechamentos de tipo conhecido são declarados como -

let sub = {
   (no1: Int, no2: Int) -> Int in 
   return no1 - no2 
}

let digits = sub(10, 20)
print(digits)

Quando executamos o programa acima usando playground, obtemos o seguinte resultado -

-10

Declarando nomes de argumentos abreviados como fechamentos

O Swift 4 fornece automaticamente nomes de argumento abreviados para fechamentos embutidos, que podem ser usados ​​para se referir aos valores dos argumentos de fechamento pelos nomes $ 0, $ 1, $ 2 e assim por diante.

var shorthand: (String, String) -> String
shorthand = { $1 }
print(shorthand("100", "200"))

Aqui, $ 0 e $ 1 referem-se ao primeiro e ao segundo argumento String da closure.

Quando executamos o programa acima usando playground, obtemos o seguinte resultado -

200

O Swift 4 facilita ao usuário representar fechamentos inline como nomes de argumentos abreviados, representando $ 0, $ 1, $ 2 --- $ n.

A lista de argumentos de closures é omitida na seção de definição quando representamos nomes de argumentos abreviados dentro de expressões de closure. Com base no tipo de função, os nomes dos argumentos abreviados serão derivados. Como o argumento abreviado é definido no corpo da expressão, a palavra-chave 'in' é omitida.

Fechamentos como funções do operador

O Swift 4 fornece uma maneira fácil de acessar os membros, fornecendo apenas funções de operador como fechos. Nos exemplos anteriores, a palavra-chave 'Bool' é usada para retornar 'verdadeiro' quando as strings são iguais, caso contrário, retorna 'falso'.

A expressão é ainda mais simples pela função do operador no fechamento como -

let numb = [98, -20, -30, 42, 18, 35]
var sortedNumbers = numb.sorted ({
   (left: Int, right: Int) -> Bool in
   return left < right
})

let asc = numb.sorted(<)
print(asc)

Quando executamos o programa acima usando playground, obtemos o seguinte resultado -

[-30, -20, 18, 35, 42, 98]

Fechamentos como reboques

Passar o argumento final da função para uma expressão de fechamento é declarado com a ajuda de 'Trailing Closures'. É escrito fora da função () com {}. Seu uso é necessário quando não é possível escrever a função embutida em uma única linha.

reversed = sorted(names) { $0 > $1}

onde {$ 0> $ 1} são representados como fechamentos finais declarados fora de (nomes).

import Foundation
var letters = ["North", "East", "West", "South"]

let twoletters = letters.map({ 
   (state: String) -> String in
   return state.substringToIndex(advance(state.startIndex, 2)).uppercaseString
})

let stletters = letters.map() { 
   $0.substringToIndex(advance($0.startIndex, 2)).uppercaseString 
}
print(stletters)

Quando executamos o programa acima usando playground, obtemos o seguinte resultado -

[NO, EA, WE, SO]

Captura de valores e tipos de referência

No Swift 4, a captura de valores de constantes e variáveis ​​é feita com a ajuda de fechamentos. Além disso, faz referência e modifica os valores para essas constantes e variáveis ​​dentro do corpo de encerramento, mesmo que as variáveis ​​não existam mais.

A captura de valores constantes e variáveis ​​é obtida usando a função aninhada, escrevendo a função com no corpo de outra função.

Uma função aninhada captura -

  • Argumentos da função externa.
  • Capture constantes e variáveis ​​definidas na função externa.

No Swift 4, quando uma constante ou variável é declarada dentro de uma função, a referência a essas variáveis ​​também é criada automaticamente pelo encerramento. Ele também fornece a facilidade de se referir a mais de duas variáveis ​​como o mesmo fechamento da seguinte forma -

let decrem = calcDecrement(forDecrement: 18)
decrem()

Aqui oneDecrement e as variáveis ​​de Decremento apontarão para o mesmo bloco de memória como referência de fechamento.

func calcDecrement(forDecrement total: Int) -> () -> Int {
   var overallDecrement = 100
   func decrementer() -> Int {
      overallDecrement -= total
      print(overallDecrement)
      return overallDecrement
   }
   return decrementer
}

let decrem = calcDecrement(forDecrement: 18)
decrem()
decrem()
decrem()

Quando executamos o programa acima usando playground, obtemos o seguinte resultado -

82
64
46

Cada vez que a função externa calcDecrement é chamada, ela invoca a função decrementer (), diminui o valor em 18 e retorna o resultado com a ajuda da função externa calcDecrement. Aqui, calcDecrement atua como um fechamento.

Mesmo que a função decrementer () não tenha nenhum argumento, o fechamento por padrão se refere às variáveis ​​'globalDecrement' e 'total' capturando seus valores existentes. A cópia dos valores para as variáveis ​​especificadas é armazenada com a nova função decrementer (). O Swift 4 lida com funções de gerenciamento de memória alocando e desalocando espaços de memória quando as variáveis ​​não estão em uso.