2015-01-13 8 views
8

Sto cercando di conoscere swift e chiusure. Sono bloccato su questo esempio.Non capisco l'esempio di chiusure in Swift

numbers.map({ 
    (number: Int) -> Int in 
    let result = 3 * number 
    return result 
}) 

Che cos'è (numero: Int) -> Int? È una funzione? Dove è definito? https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/GuidedTour.html#//apple_ref/doc/uid/TP40014097-CH2-ID1

Cosa fa la parola chiave "in"? I documenti dicono di usare "per separare gli argomenti e restituire il tipo dal corpo". Non sono sicuro di capirlo. Perché non è "in" usato per separare "let result = 3 * number" da "return result".

+2

Questa è anche una buona introduzione alle chiusure in Swift: http: //letvargo.mooo.com/a-beginners-guide-to-closures-in-swift/) –

risposta

28

Una chiusura è solo una funzione con i parametri spostato all'interno delle parentesi, con la parola chiave in per separare i parametri dal corpo della funzione. I due esempi che seguono definiscono funzioni equivalenti:

func myFunc(number: Int) -> Int { 
    let result = 3 * number 
    return result 
} 

let myClosure = { (number: Int) -> Int in 
    let result = 3 * number 
    return result 
} 

Si può effettivamente entrambi chiamare esattamente nello stesso modo:

let x = myFunc(2)  // x == 6 
let y = myClosure(2) // y == 6 

Si noti come il secondo esempio è esattamente la stessa della prima, solo nel primo esempio, i parametri (number: Int) -> Int sono al di fuori delle parentesi e nel secondo esempio i parametri sono all'interno delle parentesi, seguite dalla parola chiave in.

map funziona prendendo un array (numbers, nell'esempio) e creando un nuovo array che è il risultato dell'applicazione della funzione di chiusura a ciascun elemento in numbers. Quindi se numbers è [1, 2, 3], l'esempio precedente inizierà con 1. Applicherà la funzione di chiusura che produrrà un 3 (perché tutto ciò che fa è moltiplicare l'elemento dal primo array per 3). Lo fa per ogni elemento in numbers, fino a quando non ha prodotto un nuovo array, [3, 6, 9].

Se si desidera, è possibile chiamare map utilizzando i nomi della funzione sopra o della chiusura di cui sopra, oppure scrivendo esplicitamente all'interno di map. Tutti gli esempi indicati sono totalmente equivalenti:

let numbers = [1, 2, 3] 

// Example 1 
let times3 = numbers.map(myFunc)  // times3 == [3, 6, 9] 

// Example 2 
let timesThree = numbers.map(myClosure) // timesThree == [3, 6, 9] 

// Example 3 
let xThree = numbers.map({ (number: Int) -> Int in 
    let result = 3 * number 
    return result      // xThree == [3, 6, 9] 
}) 

noti che nell'esempio 3 è identica all'Esempio 2, solo nell'esempio 3 la chiusura è chiarita esplicitamente all'interno di map, mentre nell'esempio 2 è stato assegnato alla chiusura a una costante denominata myClosure e la costante è stata fornita a map.

Spero che questo aiuti - le chiusure sono divertenti, ma confuse.

+0

sono anche bloccato con chiusure, ma la tua risposta aiutami a capire. Grazie. –

+0

Hey grazie Roman, questo sicuramente ha aiutato. Adesso è molto chiaro per me. La spiegazione di Apple è stata un po 'troppo ripida per arrivare al primo tentativo. –

+0

Grazie mille! Mi ha davvero aiutato a capire come funziona questo frammento di codice. –

1

La funzione che stai chiamando prende una chiusura come parametro:

numbers.map({...}) 

La chiusura prevista per la funzione si aspetta di ricevere un parametro quando viene eseguito dalla funzione chiamato. Questo parametro è definito in chiusura:

(number: Int) -> Int in 

si possono ora utilizzare il parametro in il contenuto della chiusura

let result = 3 * number 
    return result 
0

Le chiusure sono blocchi di funzionalità autonomi che possono essere trasferiti e utilizzati nel codice.

Sintassi:

{(parameterName: ParameterType) -> returnType in 
    //Statements 
} 

scenario pratico: quando l'utente vuole applicare il filtro e vogliono selezionare i valori che è più di 300 (in questo caso) possiamo utilizzare le chiusure per raggiungere questo obiettivo.

var elements: [Int] = [Int]() //Declaring Empty array 
elements = [1001, 999, 555, 786, 988, 322, 433, 128, 233, 222, 201, 276, 133] 

var filteredElements = elements.map({(num: Int) -> Int? in 
    return num > 300 ? num : nil 
}) 

output: 
[Optional(1001), Optional(999), Optional(555), Optional(786), Optional(988), Optional(322), Optional(433), nil, nil, nil, nil, nil, nil] 

qui sotto il codice si può chiaramente vedere che stanno passando chiusura a elements.map function().

chiusura:

{(num: Int) -> Int? in 
     return num > 300 ? num : nil 
    } 

(num:Int) è parametro. Int? stiamo restituendo il tipo intero facoltativo.

Dopo in possiamo scrivere la tua logica.

Ulteriori informazioni sulla chiusura here.