Perché la sintassi della dichiarazione di chiusura in Swift è diversa dalla dichiarazione di funzione

3
let closure = { (args) -> ReturnT in ... }

v.s.

func function(args) -> ReturnT { ... }

Perché Apple non ha seguito il principio del rasoio di Occam e rende le dichiarazioni di chiusura e di funzione uguali? Ad esempio, la chiusura potrebbe essere definita in questo modo:

let closure = (args) -> ReturnT { ... }

Ecco come è stato implementato in JavaScript e in altri linguaggi di scripting. Anche questo sembra più ragionevole perché la funzione e la chiusura sono in realtà identiche. E, al contrario, inserire argomenti e restituire il tipo all'interno delle parentesi sembra strano e potrebbe creare problemi a un programmatore.

    
posta kelin 29.04.2016 - 14:25
fonte

1 risposta

7

Swift ha scelto la sintassi in stile lambda per i suoi parametri di funzione anche nelle normali funzioni. L'unica differenza tra una funzione ordinaria e una chiusa è il posizionamento delle parentesi e l'uso della parola chiave in .

Apple descrive Closures come "blocchi autonomi di funzionalità che possono essere trasferiti e utilizzati nel codice." Questo concetto di stile "blocco" è evidente in tutti i loro esempi.

Ad esempio, questa funzione ordinaria:

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

Può essere passato a una funzione Sort per invertire l'ordinamento:

var reversed = names.sort(backwards)

In forma di chiusura, si passa un blocco di codice alla funzione in questo modo:

reversed = names.sort( { (s1: String, s2: String) -> Bool in return s1 > s2 } )

Che non sembra molto. Tuttavia, la sintassi ti consente di fare alcune ottimizzazioni. Digita inferenza ti consente di accorciare

reversed = names.sort( { s1, s2 in return s1 > s2 } )

Resi impliciti ti permettono di abbreviare

reversed = names.sort( { s1, s2 in s1 > s2 } )

E I nomi degli argomenti abbreviati ti permettono di abbreviare

reversed = names.sort( { $0 > $1 } )

Tuttavia, la variazione di sintassi più interessante è "Trailing Closure", che consente di passare la chiusura all'ultimo argomento di metodo al di fuori delle parentesi. Perché la funzione sort richiede solo una argomento, puoi anche omettere le parentesi. Quindi ora sembra:

reversed = names.sort { $0 > $1 }

Potrebbe sembrare una piccola differenza, ma considera questo esempio:

let strings = numbers.map {
    (number) -> String in
    var number = number
    var output = ""
    while number > 0 {
        output = digitNames[number % 10]! + output
        number /= 10
    }
    return output
}

che utilizza una chiusura finale in una funzione mappa. Le bretelle non sembrano più così scomode, vero?

Ulteriori letture
The Swift Programming Lingua: chiusure

    
risposta data 29.04.2016 - 16:16
fonte

Leggi altre domande sui tag