Quick close - forced close is always completed

Is it possible to fix the closure? Just like a function with a return value MUST always be returned, it would be an ace if there was a way to force the closure to contain the syntax needed to complete.

For example, this code will not compile because the function does not always return a value:

func isTheEarthFlat(withUserIQ userIQ: Int) -> Bool {
    if userIQ > 10 {
        return false
    }
}

Similarly, I would like to define a function with a closure that will also not compile if the closure does not return. For example, the code below can never return the completion of a Handler:

func isTheEarthFlat(withUserIQ userIQ: Int, completionHandler: (Bool) -> Void) {
    if userIQ > 10 {
        completionHandler(false)
    }
}

, , , , . , - Void ?

+4
3

, , , ( ), , return.

, . , required - .

+2

, . , , :

func isTheEarthFlat(withUserIQ userIQ: Int, completionHandler: (Bool) -> Void) {
    let result: Bool
    defer {
       completionHandler(result)
    }
    if userIQ > 10 {
        result = false
    }
}

completionHandler :

func isTheEarthFlat(withUserIQ userIQ: Int, completionHandler: (Bool) -> Void) {
    let result: Bool
    defer {
       completionHandler(result)
    }
    if userIQ > 10 {
        result = false
    } else {
        result = true
    }
}

, .

+2

, . GuarenteedExecution GuarenteedExecutionResult.

A GuarenteedExecution - , , .

GuarenteedExecutionResult GuarenteedExecution. , , . isTheEarthFlat, a GuarenteedExecutionResult. GuarenteedExecutionResult - execute(argument:) GuarenteedExecution. , , , , GuarenteedExecution.

struct GuarenteedExecutionResult<R> {
    let result: R

    fileprivate init(result: R) { self.result = result }
}

struct GuarenteedExecution<A, R> {
    typealias Closure = (A) -> R

    let closure: Closure

    init(ofClosure closure: @escaping Closure) {
        self.closure = closure
    }

    func execute(argument: A) -> GuarenteedExecutionResult<R> {
        let result = closure(argument)
        return GuarenteedExecutionResult(result: result)
    }
}

( GuarenteedExecutionResult.init):

let guarenteedExecutionClosure = GuarenteedExecution(ofClosure: {
    print("This must be called!")
})

func doSomething(guarenteedCallback: GuarenteedExecution<(), ()>)
    -> GuarenteedExecutionResult<()> {
    print("Did something")
    return guarenteedCallback.execute(argument: ())
}

_ = doSomething(guarenteedCallback: guarenteedExecutionClosure)
+2

Source: https://habr.com/ru/post/1684682/


All Articles