2015-12-29 15 views
5

C'è una func:tipo di "Int -> Bool", "INT> Bool -> Int", "INT> String -> INT> Bool"

func (first: Int) -> Int -> Bool -> String { 

    return ? 
} 

Come scrivere il valore di ritorno? Sono così confuso riguardo al tipo di ritorno della funzione sopra riportata.

+2

quello che fa è più complicato e dovrebbe essere riscritto probabilmente – Fonix

+0

@Fonix - questo fa parte del supporto di programmazione funzionale che Swift ha incorporato – Cristik

+0

@Cristik non lo rende meno brutto da leggere/utilizzare. 'f (1) (2) (true)' kinda interrompe il tutto "le funzioni dovrebbero leggere come frasi" che obj-c e swift provano a usare gli sviluppatori (a ragione). potrebbe essere una buona ragione per questo ma sono sicuro che potrebbe essere evitato – Fonix

risposta

2

diciamo si definisce una chiusura

let closure: Int -> Bool 

una volta che il tipo di chiusura è nota (tipo di parametri e tipo di ritorno) , scrivendo è abbastanza semplice, si nomina la lista dei parametri, seguita dalla parola chiave in e poi il corpo della funzione (con un ritorno alla fine, se la funzione restituisce il tipo non è Void (a.k.un ())

// closure that returns if an integer is even 
closure = { integer in 
    return integer %2 == 0 
} 

Nel tuo caso, Int -> Int -> Bool -> String significa

  • una funzione che prende un int come parametro e restituisce
    • una funzione che prende un int come parametro e restituisce
      • una funzione che accetta un Bool come parametro e restituisce
        • una stringa

Un modo di scrivere che in codice:

func prepareForSum(first: Int) -> Int -> Bool -> String { 
    return { secondInteger in 
     return { shouldSumIntegers in 

     var result: Int 
     // for the sake of example 
     // if boolean is true, we sum 
     if shouldSumIntegers { 
      result = first + secondInteger 
     } else { 
      // otherwise we take the max 
      result = max(first, secondInteger) 
     } 

     return String(result) 
    } 
} 

ora è possibile utilizzarlo come quella

let sumSixteen = prepareForSum(16) // type of sumSixteen is Int -> Bool -> String 

let result1 = sumSixteen(3)(true) // result1 == "19" 
let result2 = sumSixteen(26)(false) // result2 == "26" 
9

Leggere da destra verso sinistra quando si tratta di funzioni di parsing/chiusure di chiusura. Il più giusto è il tipo di ritorno, e puoi mettere il resto tra parentesi.

Così, il vostro dichiarazione di funzione è equivalente a

func (first: Int) -> ((Int) -> ((Bool) -> String)) 

e

func (first: Int)(_ second: Int)(_ third: Bool) -> String 

anche se questo modulo non sarà più supportato in Swift 3.0 (grazie @Andrea per il testa a testa).

Questo è noto come function currying. La funzione restituisce una funzione che accetta un argomento come Int e restituisce un'altra funzione che accetta un parametro Bool e restituisce un valore String. In questo modo è possibile collegare facilmente le chiamate alle funzioni .

Così il corpo del metodo deve restituire la prima funzione della lista, quella che ha la seguente firma:

func ((Int) -> ((Bool) -> String)) 

È quindi possibile chiamare in questo modo:

f(1)(2)(true) 
+0

Pensavo che il currying fosse quando si ha una funzione che assume più parametri e la si trasforma in una funzione che restituisce una funzione che restituisce una funzione (... e così via per ogni argomento). Non è stata menzionata una funzione con più parametri nella domanda. – Vinzzz

+0

Una trasformazione di curring può finire per generare la firma della funzione in discussione. Le informazioni sul curriculum sono lì per spiegare come puoi finire con le funzioni che restituiscono funzioni che restituiscono funzioni, ecc. – Cristik

+0

Il currying è bello, purtroppo sarà rimosso in Swift 3.0 come da elenco di swift evolution su github https://github.com/apple/swift-evolution – Andrea

Problemi correlati