Classe anonyme dans swift

Existe-t-il une syntaxe ou une technique équivalente pour la classe Anonymous dans Swift? Juste une clarification Anonyme de classe en Java exemple ici - http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html

Merci!

27
demandé sur eranh 2014-06-25 15:58:39

5 réponses

il n'y a pas de syntaxe équivalente, pour autant que je sache.

en ce qui concerne les techniques équivalentes, théoriquement vous pourriez utiliser des fermetures et définir des structures et des classes à l'intérieur d'elles. Malheureusement, je ne peux pas faire marcher ça dans un terrain de jeu ou un projet sans le faire planter. Très probablement ce n'est pas prêt à être utilisé dans la version bêta actuelle.

quelque Chose comme...

protocol SomeProtocol {
    func hello()
}

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

...affiche actuellement cette erreur:

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
13
répondu hpique 2014-06-25 14:03:57

par exemple, Java listener / adaptateur pattern serait traduit en Swift comme ceci:

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)

(s'Écraser le compilateur sur la Bêta 2)

Le problème est, vous devez toujours spécifier un nom. Je ne pense pas Qu'Apple introduira jamais des classes anonymes (et des structures etc.) parce qu'il serait assez difficile à venir avec une syntaxe qui n'entrent pas en collision avec l'arrière de fermetures.

aussi dans la programmation anonyme les choses sont mauvaises. Nommer des choses aide les lecteurs à comprenez le code.

9
répondu Sulthan 2014-06-25 13:01:12

vous pouvez aussi créer une classe basique vide qui agit comme un protocole nu, et passer une fermeture à la init fonction qui remplace tout ce que vous voulez, comme ceci:

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!"

ce n'est pas techniquement "anonyme" mais ça marche de la même façon. On vous donne un shell vide d'une classe, puis vous le remplissez ou outrepassez les paramètres que vous voulez quand vous l'initialisez avec une fermeture.

c'est essentiellement la même chose, sauf qu'au lieu de répondre aux attentes d'un protocole, il supplante les propriétés d'une classe.

9
répondu Aaron Rasmussen 2015-01-28 23:49:20

pas de syntaxe de classe anonyme dans Swift. Mais, vous pouvez créer une classe à l'intérieur d'une classe et les méthodes de la classe:

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));
    }
}
7
répondu karthikPrabhu Alagu 2017-05-05 06:14:29

c'est Ce que j'ai fait (modèle Observateur). Vous pouvez utiliser les fermetures de la même manière que vous utiliseriez les classes anonymous en Java. Avec des limites évidentes de cours.

class Subject {
   // array of closures
   var observers: [() -> Void] = []

   // @escaping says the closure will be called after the method returns
   func register(observer: @escaping () -> Void) {
       observers.append(observer)
   }

   func triggerEvent() {
       observers.forEach { observer in
            observer()
       }
   }
}

var subj = Subject()
// you can use a trailing closure
subj.register() {
    print("observerd")
}

// or you can assign a closure to a variable so you can maybe use the reference to removeObserver() if you choose to implement that method
var namedObserver: () -> Void = {
    print("named observer")
}
subj.register(observer: namedObserver)

subj.triggerEvent()
// output:
// observerd
// named observer
0
répondu Antonín Karásek 2018-06-01 17:49:56