Подтвердить что ты не робот

Анонимный класс в быстром

Есть ли эквивалентный синтаксис или метод для анонимного класса в Swift? Просто для разъяснения Анонимный класс в примере Java здесь - http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html

Благодарю!

4b9b3361

Ответ 1

Насколько я знаю, нет эквивалентного синтаксиса.

Что касается эквивалентных методов, теоретически вы можете использовать закрытие и определять структуры и классы внутри них. К сожалению, я не могу заставить это работать на детской площадке или в проекте, не сделав это крушением. Скорее всего, это не готово к использованию в текущей бета-версии.

Что-то вроде...

protocol SomeProtocol {
    func hello()
}

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

... в настоящее время выводит эту ошибку:

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

Ответ 2

Например, шаблон Java-слушателя/адаптера будет переведен в Swift следующим образом:

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)

(Сбой компилятора на бета-версии 2)

Проблема в том, что вы всегда должны указывать имя. Я не думаю, что Apple когда-нибудь представит анонимные классы (и структуры и т.д.), Потому что было бы довольно сложно получить синтаксис, который не сталкивается с трейлинг-закрытиями.

Также в программировании анонимных вещей плохо. Именование вещей помогает читателям понять код.

Ответ 3

Вы также можете создать базовый пустой класс, который действует как открытый протокол, и передать закрытие функции init которая отменяет все, что вы хотите, например:

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

Это не технически "анонимно", но работает одинаково. Вам предоставляется пустая оболочка класса, а затем вы заполняете ее или переопределяете все параметры, которые вы хотите, когда вы инициализируете ее закрытием.

Это в основном то же самое, за исключением того, что вместо выполнения ожиданий протокола он переопределяет свойства класса.

Ответ 4

Нет синтаксиса анонимного класса в Swift. Но вы можете создать класс внутри методов класса и класса:

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

Ответ 5

Это то, что я закончил делать (шаблон наблюдателя). Вы можете использовать блокировки аналогичным образом, чтобы использовать анонимные классы в Java. Конечно, с очевидными ограничениями.

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