Использование отсрочки внутри, если - PullRequest
0 голосов
/ 11 июля 2019

Я хочу выполнить некоторый код после выхода из функции, только если какой-то код завершится успешно, как это:

if object.open {
    defer {
        object.close()
    }
}
...
dome some stuff...
...
return
}

Проблема в том, что defer выполняется сразу после условия if. Как я понимаю, это правильное поведение.

Тогда возникает вопрос: Можно отложить код блока внутри if, чтобы запустить после завершения функции. Я попробовал вложенные отсрочки, но это не сработало. Спасибо за любую помощь!

Ответы [ 2 ]

1 голос
/ 11 июля 2019

Используя defer, невозможно напрямую отложить что-либо, что произойдет за пределами текущей области, например условия if, в котором вы находитесь. Однако можно отложить что-то безоговорочно и переместите условие в defer:

defer {
    if object.isOpen { object.close() }
}

Более общее решение в этом направлении будет выглядеть примерно так:

var deferred: (() -> Void)? = nil
defer { deferred?() }
if object.isOpen {
    deferred = { object.close() }
}

Это более общее решение позволило бы отложить разные вещи на основе разных условий, но, очевидно, самое большее по одному за раз. Для поддержки более чем одного вы, конечно, можете использовать массив:

var deferred = [(() -> Void)]()
defer {
    for f in deferred.reversed() { f() }
}
if object1.isOpen {
    deferred.append { object1.close() }
}
if object2.isOpen {
    deferred.append { object2.close() }
}

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

0 голосов
/ 11 июля 2019

Из документации :

Оператор отсрочки используется для выполнения кода непосредственно перед передачей управления программой за пределы области, в которой оператор отсрочки появляется в .

Итак, чтобы ответить на ваш вопрос:

Можно отложить код блока внутри if, если запускать после завершения функции.

Нет.defer запускается всякий раз, когда заканчивается его объем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...