Я хочу определить переменные замыкания и использовать их позже. Как мне это сделать? - PullRequest
0 голосов
/ 28 декабря 2018

Ниже приведен один протокол, который имеет две переменные замыкания и функцию.И есть также класс, соответствующий протоколу.

import Foundation

protocol TestProtocol: class {
    var firstClosure: () -> () { get set }
    var secondClosure: () -> () { get set }
    func testFunction()
}

extension TestProtocol {
    func testFunction() {
        _ = firstClosure
        _ = secondClosure
    }
}

class A: TestProtocol {
    var firstClosure: () -> ()
    var secondClosure: () -> ()

    var number = 0

    init() {
        print(number)
        firstClosure = {
            self.number = 1
        }()
        print(number)
        secondClosure = {
            self.number = 2
        }()
        print(number)
        testFunction()
        print(number)
    }
}

let a = A()

Мой ожидаемый результат - 0, 0, 0, 2. Но, когда я определяю переменную закрытия, переменная закрытия выполняется немедленно.Что мне делать?

1 Ответ

0 голосов
/ 28 декабря 2018

Проблема в том, что вы не определяете замыкания, вы определяете Void s из-за того, что вы выполняете замыкания сразу после их определения, записывая () после замыкания.Типы firstClosure и secondClosure оба Void, что является typealias для ().Если вы хотите объявить замыкание, которое не принимает входные аргументы и не возвращает никакого значения (или, скорее, возвращает Void), вам нужно объявить его как () -> ().

protocol TestProtocol: class {
    var firstClosure: () -> () { get set }
    var secondClosure: () -> () { get set }
    func testFunction()
}

extension TestProtocol {
    func testFunction() {
        firstClosure()
        secondClosure()
    }
}

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

class A: TestProtocol {
    var number = 0
    lazy var firstClosure: () -> Void = {
        self.number = 1
    }
    lazy var secondClosure: () -> Void = {
        self.number = 2
    }
}

A().testFunction()
...