Класс Swift: объявляйте переменные с замыканиями, указывающими на функции-члены - PullRequest
0 голосов
/ 25 июня 2018

Использование swift 4.2 с xcode10 beta

Я пытаюсь создать класс swift, который хранит в качестве поля закрытие, которое будет указывать на функцию-член класса.

Идея - это вариант паттерна Стратегия.Я хочу иметь возможность изменить то, что функция вызывается во время выполнения.В этом примере публичная функция f () вызывает внутреннее закрытие.Закрытие должно хранить либо f_release, либо f_debug, где позже просто добавьте несколько отладочных операторов печати:

class MyClass {

    var n:Int = 0
    var aFunc: (Int) -> ()

    init() {
        aFunc = f_release
    }

    public func f(number:Int) {
        aFunc(number)
    }

    func f_release(number:Int) {
        n = n + number
    }

    func f_debug(number:Int) {
        print(n)
        f_release(number:number)
        print(n)
    }
}

Мои проблемы возникают при инициализации.В приведенном выше примере компилятор жалуется: _'self 'используется в вызове метода' f_release 'до инициализации всех сохраненных свойств_

Я попытался инициализировать переменную aFunc значением по умолчанию, чтобы исправить эту проблему, заменив строку

    var aFunc: (Int) -> ()

со строкой

    var aFunc: (Int) -> () = f_release

Однако для этого случая компилятор теперь жалуется: Невозможно преобразовать значение типа '(MyClass) -> (Int) -> () 'к указанному типу' (Int) -> () '

Что я делаю не так?Заранее спасибо

Ответы [ 2 ]

0 голосов
/ 25 июня 2018

Назначение значения внутри инициализатора не может работать, так как вы пытаетесь присвоить свойство экземпляра (или функцию в вашем конкретном случае) другому свойству экземпляра, но в инициализаторе ни один из них не гарантированно будет инициализирован.

Вы можете решить свою проблему, объявив aFunc ленивым. Вам больше не понадобится инициализатор.

lazy var aFunc: (Int) -> () = f_release
0 голосов
/ 25 июня 2018

Попробуйте это:

 class MyClass {

    var n:Int = 0
    lazy var aFunc: (Int) -> () = f_release

    public func f(number:Int) {
        aFunc(number)
    }

    func f_release(number:Int) {
        n = n + number
    }

    func f_debug(number:Int) {
        print(n)
        f_release(number:number)
        print(n)
    }
}
...