Xavier L.
Xavier L.

Reputation: 747

Returning after calling completion handler, or return completion handler parameter?

I have a method that can be summed up to look like this:

func apply(username: String, email: String, password: String,
           onDone: @escaping (_ error: Error?) -> ())
{
    //Do async stuff
    do
    {
        try asyncGood()
        onDone(nil)
        return
    }
    catch
    {
        onDone(error)
        return
    }
}

What's the difference between doing:

return onDone(error)

versus

onDone(error)
return

?
Does it just save an extra line of code? I don't see any difference between the two. Am I missing some fundamental aspect of asynchronous Swift programming?

In your opinion, should I always try to condense everything down such that onDone(...) only gets called once at the end?

Upvotes: 1

Views: 2109

Answers (3)

Maxim Kosov
Maxim Kosov

Reputation: 1980

There is no difference. In fact, there is no need for return keyword at all.

For swift all the following declaration is equivalent:

func doNothing() {
}

func doNothing2() -> Void {
}

func doNothing3() -> () {
}

func doNothing4() {
    return ()
}

func doNothing5() -> Void {
    return ()
}

When you return () you return nothing. No return is exactly the same as return nothing. Functions returning Void may be equivalently used as following

doNothing()

var result = doNothing()

More, Void can also be used as a type parameter which is a very powerful feature:

func genericCall<T>(_ f: () -> T) -> T {
    return f()
}

var result1 = genericCall { print("test") } // result1 is Void
var result2 = genericCall { return 5 } // result2 is Int

Answering your initial question, I would suggest to omit return at all

func doStuffAsync(_ callback: @escaping (Error?) -> Void) {
    // Just an example. Could be any other async call.
    DispatchQueue.main.async {
        do {
            try doStuff()
            callback(nil)
        }
        catch {
            callback(error)
        }
    }
}

Upvotes: 1

Bilal
Bilal

Reputation: 19156

Both are same. apply function return type is Void and onDone closure return type is also Void. So both are same.

return onDone(error)

or

onDone(error)
return

or you can just ignore return because return type is Void

onDone(error)

Upvotes: 1

Sweeper
Sweeper

Reputation: 274358

Semantically, both cases are the same. You are basically saying:

return ()

Your method is declared to return (), and since the onDone closure also returns a (), you can say return onDone(error). The return types match.

However, I find writing them in 2 separate lines more readable:

// This clearly shows that you are doing 2 separate things
onDone(error) // call the completion handler
return // return

Or even omit the return!

onDone(error)
// there will be an implicit return at the end of the method.

Upvotes: 2

Related Questions