Почему оценка задержки автоматического закрытия и нормального закрытия нет? - PullRequest
0 голосов
/ 19 июня 2020

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

Я позаимствовал фрагмент с автоматическим закрытием у John Sundell , чтобы сравнить с / без автоматического замыкания.

func assert2(_ expression: @autoclosure () -> Bool,
            _ message: @autoclosure () -> String) {
    guard isDebug else {
        return
    }

    // Inside assert we can refer to expression as a normal closure
    if !expression() {
        assertionFailure(message())
    }  
}
func assert3(_ expression: () -> Bool,
            _ message: () -> String) {
    guard isDebug else {
        return
    }

    // Inside assert we can refer to expression as a normal closure
    if !expression() {
        assertionFailure(message())
    }  
}

Но, похоже, message() не будет выполняться в обоих случаях.

Единственная разница для меня в том, что мне нужно закрывать вручную:

override func viewDidLoad() {
        super.viewDidLoad()

        assert2(false, "hello2")
        assert3({return false}, {return "hello3"})
}

Есть ли какая-то другая причина, по которой Apple и Джон Санделл говорят, что автоматическое закрытие задерживает выполнение? Например, выполняется ли предварительная оценка нормального закрытия из-за оптимизации из Xcode? Или какие-то другие причины, по которым закрытие ведет себя подобным образом?

Пожалуйста, предоставьте официальный документ, если есть какой-либо, который прямо объясняет этот момент.

1 Ответ

1 голос
/ 19 июня 2020

Я думаю, вы неправильно поняли различие, которое пытается провести документация. Когда в документации написано:

Автоматическое закрытие позволяет отложить оценку, потому что код внутри не запускается, пока вы не вызовете закрытие.

Это не сравнение @autoclosure () -> Bool ("автоматическое закрытие") против () -> Bool ("нормальное закрытие"). Он сравнивает @autoclosure () -> Bool с Bool.

В документации предполагается, что вызывающий объект остается тем же самым, особенно в случае, если вызывающий передает некоторые выражения в метод. Например, для такого вызывающего кода:

assert(someBoolFunction(), someStringFunction())

Использование @autoclosure позволит запускать someBookFunction позже (или не запускать вообще), тогда как принятие Bool вызовет someBoolFunction для вызова немедленно, даже до вызова assert. Это потому, что @autoclosure указывает, что любое переданное выражение заключено в закрытие с помощью магии синтаксиса c сахара.

Обратите внимание, что изменение параметра функции с Bool на @autoclosure () -> Bool обычно не критическое изменение для вызывающего (вызывающий по-прежнему сможет передавать выражения в функцию), поэтому это значимое сравнение.

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