2014-06-25 12 views
24

Czy istnieje odpowiednia składnia lub technika dla klasy Anonim w Swift? Tylko dla wyjaśnienia Klasa anonimowa w języku Java na przykład tutaj - http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.htmlKlasa anonimowa w szybkim tempie

Dzięki!

+0

Nie wygląda na to. Anonimowe zajęcia to jedna z moich ulubionych funkcji Java, więc mam nadzieję, że w końcu będziemy mieli je w Swift. – hpique

+0

@ hpique Prawda, są dobre w Javie, ale nie są tak naprawdę potrzebne w językach, które mają zamknięcia i klasy, które można zadeklarować w metodach. Wszystkie wzorce słuchacza/adaptera w Javie mogą być łatwo implementowane przy użyciu zamknięć, bez klas anonimowych. – Sulthan

+0

@Sulthan Oczywiście, możesz dużo zrobić z zamknięciami i wewnętrznymi klasami. Ale dzięki szerokiemu stosowaniu protokołów w Swift sądzę, że anonimowe klasy mogą być bardzo przydatne w niektórych sytuacjach. – hpique

Odpowiedz

12

Nie ma równoważnej składni, o ile wiem.

Jeśli chodzi o równoważne techniki, teoretycznie można użyć zamknięć i zdefiniować wewnątrz nich klasy i klasy. Niestety, nie mogę zmusić tego do pracy na placu zabaw lub w projekcie bez powodowania awarii. Najprawdopodobniej nie jest to gotowe do użycia w bieżącej wersji beta.

Coś ...

protocol SomeProtocol { 
    func hello() 
} 

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

... obecnie generuje ten błąd:

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

Oznaczono jako rozwiązany, ale nadal można testować na beta2 – eranh

6

Nie anonimowa klasa składni w Swift. Ale, można utworzyć klasę wewnątrz klasy i klasy metod:

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 jest czasami tak dziwaczny. Z jednej strony zmusza cię do umieszczenia nawiasów klamrowych wokół jednoliniowych instrukcji 'if' i do uczynienia instrukcji switcha wyczerpującymi, a jednocześnie pozwala ci zdefiniować całą klasę wewnątrz * body * metody. smh – devios1

8

Na przykład, Java wzór słuchacz/adapter będzie tłumaczone na Swift tak:

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) 

(Upaść kompilator w wersji Beta 2)

Problem polega na tym, że zawsze musisz podać nazwę. Nie sądzę, że Apple kiedykolwiek wprowadzi anonimowe klasy (i konstrukcje itd.), Ponieważ trudno byłoby uzyskać składnię, która nie koliduje z końcowymi zamknięciami.

Również w programowaniu anonimowe rzeczy są złe. Nazywanie rzeczy pomaga czytelnikom zrozumieć kod.

+0

Zgadzam się, że programowanie anonimowe jest złe. Potrzebuję go do testów.Biorąc pod uwagę, że w tej chwili nie ma dobrego szyderczego schematu, zbytnim bólem jest podklasować każdą próbę. – eranh

8

Można również utworzyć podstawowy pustą klasę, która działa jak gołej protokół i przekazać zamknięcie do funkcji init że nadpisuje cokolwiek chcesz, na przykład:

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

To nie jest technicznie „anonimowy” ale działa to w ten sam sposób. Otrzymujesz pustą powłokę klasy, a następnie wypełniasz ją lub zastępujesz parametry, które chcesz, gdy zainicjujesz je z zamknięciem.

Zasadniczo to samo, z wyjątkiem tego, że zamiast spełnić oczekiwania protokołu, przesłonił właściwości klasy.

+0

Brilliant. Dzięki. –

Powiązane problemy