Anonymous class in swift

后端 未结 5 1372
被撕碎了的回忆
被撕碎了的回忆 2020-12-10 00:30

Is there an equivalent syntax or technique for Anonymous class in Swift? Just for clarification Anonymous class in Java example here - http://docs.oracle.com/javase/tutorial

相关标签:
5条回答
  • 2020-12-10 01:07

    No anonymous class syntax in Swift. But, you can create a class inside a class and class methods:

    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 讨论(0)
  • 2020-12-10 01:14

    There is no equivalent syntax, as far as I know.

    Regarding equivalent techniques, theoretically you could use closures and define structs and classes inside them. Sadly, I can't get this to work in a playground or project without making it crash. Most likely this isn't ready to be used in the current beta.

    Something like...

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

    ...currently outputs this error:

    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 讨论(0)
  • 2020-12-10 01:19

    You can also create a basic empty class that acts like a bare protocol, and pass a closure to the init function that overrides anything you want, like this:

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

    It is not technically 'anonymous' but it works the same way. You are given an empty shell of a class, and then you fill it in or override whatever parameters you want when you initialize it with a closure.

    It's basically the same, except instead of fulfilling the expectations of a protocol, it is overriding the properties of a class.

    0 讨论(0)
  • 2020-12-10 01:22

    This is what I ended up doing (Observer pattern). You can use closures in a similar way you would use anonymous classes in Java. With obvious limitations of course.

    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 讨论(0)
  • 2020-12-10 01:23

    For example, Java listener/adapter pattern would be translated to Swift like this:

    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 the compiler on Beta 2)

    The problem is, you always have to specify a name. I don't think Apple will ever introduce anonymous classes (and structs etc.) because it would be pretty difficult to come with a syntax that doesn't collide with the trailing closures.

    Also in programming anonymous things are bad. Naming things help readers to understand the code.

    0 讨论(0)
提交回复
热议问题