No, questo non è attualmente possibile. Se fosse possibile, la sintassi che ci si aspetta sarebbe:
public typealias ArrayClosure<T> = (array:[T]?) -> Void
Si potrebbe quindi utilizzarlo come ArrayClosure<Int>
. Ma non è attualmente legale.
Detto questo, non raccomando questi alias di questo tipo. Oscurano più di quanto non illuminino. Confronta questa firma:
func foo(onError: FailureClosure)
con:
func foo(onError: NSError? -> Void)
Per salvare solo un paio di caratteri, si forza il chiamante di indovinare cosa FailureClosure
passaggi. I tag error
o progress
non sono di grande aiuto (è comunque necessario utilizzare progress in ...
).
L'un caso che fa un sacco di senso è intorno progress
, ma penso che il tipo che si desidera c'è:
public typealias Progress = Float32
Non fraintendetemi qui, tipo aliasing può essere molto utile quando si crea un nuovo tipo. Progress
è un tipo che sembra essere implementato come float. Ma molto di quello che stai facendo (sicuramente con ArrayClosure
, e in misura minore con gli altri) è solo creando una nuova sintassi senza creare un nuovo tipo, e questo è più spesso confuso che utile.
Per chiamare il vostro esempio specifico, e perché l'uso eccessivo di tipo alias può causare a complicare il vostro disegno:
func foo(failure: ((error: NSError?) ->())? = nil)
Hai ragione che questo è davvero complicato. Confronta:
func foo(failure: NSError -> Void = {_ in return})
Due grandi cambiamenti qui. Non c'è motivo di avere un blocco di errore che richiede un errore opzionale. Passa sempre un errore (se non ci sono errori, perché si dovrebbe chiamare failure
?). E non c'è motivo per cui il blocco di errore sia opzionale. Se vuoi davvero un valore predefinito, basta fare in modo che il valore predefinito non faccia nulla. Sono stati eliminati due optionals e tutto il codice di consumo e implementazione diventa più semplice. Pensa sempre attentamente se qualcosa deve assolutamente essere opzionale. Gli optionals aggiungono molta complessità; non aggiungerli leggermente.
Personalmente, mi piacerebbe probabilmente fare questo con un sovraccarico, invece, in molti casi:
func foo(#failure: NSError -> Void) { ... }
func foo() {
foo(failure:{ _ in return })
}
Penso solo che sia un po 'più facile da capire cosa sta succedendo. Ma in entrambi i casi va bene.
EDIT (dicembre 2014): Dopo aver scritto Swift per qualche mese, ho cresciuto più affezionato @ approccio di David nei commenti qui sotto, che è quello di utilizzare un optional per la chiusura, ma non per l'errore. In particolare, data la sintassi di concatenazione opzionale di Swift (failure?()
), spesso risulta più chiara.
func foo(failure: (NSError -> Void)? = nil)
Un dettaglio che vorrei sottolineare è che è possibile definire "typealias" nelle classi in cui è definito 'T'. Se 'T' è un tipo generico del tuo oggetto, puoi creare e usare' typealias'es come normale all'interno di quella classe. Una nota se lo fai: al di fuori della classe, le 'typealias' non sono definite, quindi vedranno ancora la sintassi completa della chiusura. – vrwim