2014-06-25 6 views
24

Esiste una sintassi o una tecnica equivalente per la classe Anonymous in Swift? Giusto per chiarimenti. Esempio di classe anonima in Java qui - http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.htmlClasse anonima in swift

Grazie!

+0

Non sembra. Le classi anonime sono una delle mie funzionalità Java preferite, quindi spero di averle eventualmente in Swift. – hpique

+0

@hpique Vero, sono buoni in Java ma non sono realmente necessari in lingue che hanno chiusure e classi che possono essere dichiarate all'interno dei metodi. Tutti i modelli di listener/adapter in Java potrebbero essere implementati facilmente utilizzando le chiusure, senza classi anonime. – Sulthan

+0

@Sulthan Certo, puoi fare molto con chiusure e classi interne. Ma con l'ampio uso di protocolli in Swift penso che le classi anonime potrebbero essere davvero utili in alcune situazioni. – hpique

risposta

12

Non esiste una sintassi equivalente, per quanto ne so.

Per quanto riguarda le tecniche equivalenti, teoricamente è possibile utilizzare chiusure e definire strutture e classi al loro interno. Purtroppo, non riesco a farlo funzionare in un parco giochi o in un progetto senza farlo schiantare. Molto probabilmente questo non è pronto per essere utilizzato nella versione beta corrente.

Qualcosa di simile ...

protocol SomeProtocol { 
    func hello() 
} 

let closure :() ->() = { 
    class NotSoAnonymousClass : SomeProtocol { 
     func hello() { 
      println("Hello") 
     } 
    } 
    let object = NotSoAnonymousClass() 
    object.hello() 
} 

... attualmente genera questo errore:

invalid linkage type for global declaration 
%swift.full_heapmetadata* @_TMdCFIv4Test7closureFT_T_iU_FT_T_L_19NotSoAnonymousClass 
LLVM ERROR: Broken module found, compilation aborted! 
Command /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift failed with exit code 1 
+0

Contrassegnato come risolto ma ancora in grado di testare su beta2 – eranh

6

No sintassi classe anonima a Swift. Ma, si può creare una classe all'interno di una classe e di classe metodi:

class ViewController: UIViewController { 

    class anonymousSwiftClass { 
     func add(number1:Int, number2:Int) -> Int { 
      return number1+number2; 
     } 
    } 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     // Do any additional setup after loading the view, typically from a nib. 

     class innerSwiftClass { 
      func sub(number1:Int, number2:Int) -> Int { 
       return number1-number2; 
      } 
     } 

     var inner = innerSwiftClass(); 
     println(inner.sub(2, number2: 3)); 

     var anonymous = anonymousSwiftClass(); 
     println(anonymous.add(2, number2: 3)); 
    } 
} 
+0

Swift è così bizzarro a volte. Da una parte ti costringe a mettere parentesi graffe attorno alle istruzioni 'if' su una sola riga e a rendere esaustive le istruzioni switch, ma allo stesso tempo ti permette di definire un'intera classe all'interno del * body * di un metodo. smh – devios1

8

Per esempio, Java ascoltatore/adattatore modello sarebbe tradotto in Swift in questo modo:

protocol EventListener { 
    func handleEvent(event: Int) ->() 
} 

class Adapter : EventListener { 
    func handleEvent(event: Int) ->() { 
    } 
} 

var instance: EventListener = { 
    class NotSoAnonymous : Adapter { 
     override func handleEvent(event: Int) { 
      println("Event: \(event)") 
     } 
    } 

    return NotSoAnonymous() 
}() 

instance.handleEvent(10) 

(Crashing il compilatore su Beta 2)

Il problema è che devi sempre specificare un nome. Non penso che Apple introdurrà mai classi anonime (e le strutture, ecc.) Perché sarebbe piuttosto difficile venire con una sintassi che non si scontrasse con le chiusure finali.

Anche nella programmazione le cose anonime sono cattive. La denominazione delle cose aiuta i lettori a comprendere il codice.

+0

Sono d'accordo che la programmazione anonima è cattiva. Ne ho bisogno per test-mock.Dato che al momento non esiste una buona struttura di derisione, è troppo doloroso per sottoclasse ogni singolo finto. – eranh

8

È inoltre possibile creare una classe vuota di base che agisce come un protocollo nuda, e passare una chiusura alla funzione init che prevale su tutto quello che vuoi, in questo modo:

class EmptyClass { 

    var someFunc:() ->() = { } 

    init(overrides: EmptyClass -> EmptyClass) { 
     overrides(self) 
    } 
} 

// Now you initialize 'EmptyClass' with a closure that sets 
// whatever variable properties you want to override: 

let workingClass = EmptyClass { ec in 
    ec.someFunc = { println("It worked!") } 
    return ec 
} 

workingClass.someFunc() // Outputs: "It worked!" 

Non è tecnicamente 'anonymous' ma funziona allo stesso modo. Ti viene assegnata una shell vuota di una classe e quindi la riempi o la sovrascrivi di qualsiasi parametro desideri quando lo si inizializza con una chiusura.

È praticamente lo stesso, tranne che per soddisfare le aspettative di un protocollo, sta ignorando le proprietà di una classe.

+0

Brillante. Grazie. –