2015-06-18 17 views
10

Flush con entusiasmo dall'estensione di Bool, ho pensato che sarebbe stato divertente estendere le chiusure in Swift (lo abbiamo fatto senza problemi in Smalltalk, quindi perché no?).Non è possibile estendere la chiusura in Swift?

Ecco il mio parco giochi:

typealias NiladicClosure =() ->() 

extension NiladicClosure { 
    var theAnswerToLife:Int { 
     return 42 
    } 
} 

let block:NiladicClosure = {} 

block.theAnswerToLife 

Non funziona, dicendo che NiladicClosure does not have a member named 'theAnswerToLife'. Guardando nella console, ho un po 'più informazioni:

Playground execution failed: /var/folders/2k/6y8rslzn1m95gjpg534j7v8jzr03tz/T/./lldb/33726/playground119.swift:3:1: error: non-nominal type 'NiladicClosure' cannot be extended 
extension NiladicClosure { 
^   ~~~~~~~~~~~~~~ 

Che cos'è un non-nominal type? C'è un modello/soluzione?

Altre domande simili precedenti a Swift 2, erano anche abbastanza specifiche che le persone offrivano soluzioni alternative all'estensione specifica. Mi interessa sapere se le chiusure Swift siano oggetti di prima classe a cui aggiungere comportamenti aggiuntivi, come altre cose in Swift.

+1

Non è possibile estendere le chiusure. Confronta http://stackoverflow.com/questions/28317625/can-i-extend-tuples-in-swift (che riguarda l'estensione delle tuple, ma la stessa risposta vale per le funzioni/chiusure). –

+0

Qualche idea _WHY_ tuple e chiusure non sono estendibili? Nel caso della chiusura, è perché le chiusure non sono mai realmente reificate con un oggetto reale (o una struttura)? (almeno, non riesco a vedere da nessuna parte dove lo fanno) –

+1

@TravisGriggs È "[principalmente una limitazione di implementazione] (https://twitter.com/jckarter/status/611656674391097344)". –

risposta

8

Che cos'è un tipo non nominale?

A nominal type è un tipo con un nome esplicito. Un tipo non nominale è un tipo senza tale nome, ad esempio () ->(). I tipi composti, comprese chiusure e tuple (come (Int, String)) non possono essere estesi.

C'è un modello/soluzione alternativa?

Si potrebbe utilizzare la composizione, invece di estensioni, magari utilizzando le nuove funzionalità di protocollo di Swift 2:

typealias NiladicClosure =() ->() 

protocol NiladicClosureProtocol { 
    var someClosure : NiladicClosure? {get} 
} 

protocol SorryForTheInconvenience { 
    var theAnswerToLife : Int {get} 
} 

extension SorryForTheInconvenience { 
    var theAnswerToLife : Int { 
     return 42 
    } 
} 

struct SomethingAwesome : NiladicClosureProtocol, SorryForTheInconvenience { 
    var someClosure : NiladicClosure? 
} 

let foo = SomethingAwesome() 
foo.theAnswerToLife // 42 
+0

"È possibile utilizzare la composizione anziché le estensioni, forse utilizzando le nuove funzionalità del protocollo di Swift 2." Non sono sicuro di come funzionerebbe. Potrei creare un protocollo 'AnswersTheBigQuestion', ma non sarei in grado di estendere il tipo' non-nominale' per adottare quel protocollo, giusto? Dal momento che apparentemente non puoi estenderli. –

+0

@TravisGriggs Ho appena aggiunto un esempio. Potresti creare una struct che * abbia * un 'NiladicClosure', invece di fare qualcosa che * sia * un' NiladicClosure'. –

Problemi correlati