Anonymous class in swift

馋奶兔 提交于 2019-11-28 09:37:09

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

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.

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.

karthikPrabhu Alagu

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));
    }
}

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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!