Asım Gündüz
Asım Gündüz

Reputation: 1297

Difference between Closure Functions and Functions

I'm trying to learn swift and came across closures got the hang of it but still I have a question to ask, couldn't find any answers on the internet and I'm not sure if it's appropriate to ask here but I really need an answer on this.

say we have the following class

class Human{
var gender:String?

 private func fCheckGender(pGender:String?){
    guard pGender != nil else {
        print("Gender not specified")
        return
    }

    if pGender == "M"{
        print("Male")
    }
    else if pGender == "F"{
        print("Female")
    }
    else{
        print("gender Unknown")
    }
}

private func cCheckGender( pGender:@autoclosure ()->(String?)){

    guard pGender() != nil else {
        print("Gender not specified")
        return
    }

    if pGender() == "M"{
        print("Male")
    }
    else if pGender() == "F"{
        print("Female")
    }
    else{
        print("gender Unknown")
    }
}

func  MyCheckGender(){

    fCheckGender(pGender: gender)
    cCheckGender(pGender: gender)
}

}

var myHuman:Human = Human()

myHuman.gender = "M"

myHuman.MyCheckGender()

I would like to know the difference of

fCheckGender and cCheckGender when and where should I use the closures

Thanks in advance!

P.S I have intentionally used void->String ()->(String?) I only want to learn the difference in this scenario. I'm sorry for my bad english

Upvotes: 2

Views: 1841

Answers (2)

Gulsan Borbhuiya
Gulsan Borbhuiya

Reputation: 199

Function

In the function createUser the firebase runs background of the app so when the user enters button of the login app the function "RegisteredButtonPressed" is trigged. Inside the registeredButtonPressed function the username & password are given by the user if its correct then "completion" function is trigerred. After that "completed" function will be activated the it prints into console.

same code concept I have written in closure.

class Firebase {
func createUser (username: String, password: String, completion: (Bool, Int) -> Void) {

    let isSuccess = true
    let userID = 123

    completion(isSuccess, userID)
}


}


class MYApp {

func registerButtonPressed () {

    let firebase = Firebase()
    firebase.createUser(username: "Gullu", password: "123456", completion: completed(isSuccess:userID:))

}
func completed (isSuccess: Bool, userID: Int) {

    print("Registration id is success \(isSuccess)")
    print("User id is \(userID)")

}
}

Closure

Converting func keyword to closure

  1. remove the func keyword & name of function
  2. Bring the starting curly bracket after func starts in the beginning (in "func completed" after userid: Int a curly bracket is there , so bring it before the second bracket starts).
  3. Replace it with "in" keyword
  4. instead of calling the completed function cut paste the 3rd point above code & paste it to completion inside firebase.creativeUser
  5. Delete the completion parameter to make it trailing closure

    class MYApp {
    
    func registerButtonPressed () {
    
    let firebase = Firebase()
    firebase.createUser(username: "Gullu", password: "123456") {
        (isSuccess: Bool, userID: Int)  in
    
        print("Registration id is success \(isSuccess)")
        print("User id is \(userID)")
    
    }
    
    
    }
    
    }
    

Upvotes: 0

user1046037
user1046037

Reputation: 17695

Closure:

  • Closure is a block of code, treat it like an unnamed function.
  • When a closure is passed as an argument, the closure is not evaluated till the code inside the function invokes the argument.

Auto closure:

  • Auto closure is just a closure which packages the parameter values along with it.
  • When you define an autoclosure, there would be no parameters to the closure.

Difference between fCheckGender and cCheckGender:

  • fCheckGender takes a String value as an argument.
  • cCheckGender takes closure as an argument.
  • When cCheckGender is invoked, the closure is passed an argument, at this point, the closure is only passed as an argument, the closure is not executed. Only when the closure parameter is used inside the function, the closure gets executed.

The example you have stated might not be the best one to demonstrate the difference.

Let's consider a different example:

Example:

func add(a: Int, b: Int) -> Int {

    print("add")

    return a + b
}

func f1(pValue: Int) {

    print("f1")

    print("value = \(pValue)")
}

func f2(pClosure: (Int, Int) -> Int, pA: Int, pB: Int) {

    print("f2")

    let value = pClosure(pA, pB)

    print("value = \(value)")
}

//In autoclosure the closure always takes no parameters, because the closure is packaged with parameter values while invoking
func f3(pClosure: @autoclosure () -> Int) {

    print("f3")

    let value = pClosure()

    print("value = \(value)")
}

f1(pValue: add(a: 10, b: 20))
print("=====================\n")

f2(pClosure: add, pA: 10, pB: 20)
print("=====================\n")

f3(pClosure: add(a: 10, b: 20))
print("=====================\n")

Output:

add
f1
value = 30
=====================

f2
add
value = 30
=====================

f3
add
value = 30
=====================

Explanation of example:

  • In the function f1 pValue is an Int value.
  • So when f1 is invoked, the add is evaluated
  • In the functions f2 and f3 pClosure is a closure.
  • pClosure (closure) is not evaluated till it is invoked inside the function.

Note:

  • Focus on f3 first which accepts a closure as the argument.
  • Once you fully understand f3, then examine f2.
  • Auto closure captures the parameter values when it is invoked and later uses it.

Why and when do we need to pass a closure instead of a value:

  • There might be a scenario, where you would like to defer the execution of add till the time the function f2 invokes it.
  • There might be a scenario, where you make an asynchronous request and you want a piece of code to execute when the request completes. In this case you might pass a closure. (Closure need not always return a value, it is an unnamed function, so it can accept parameters)

Why and when do we need to an autoclosure:

  • When you want to defer the execution of add and also capture the value of it's parameters.

Suggestion:

  • Though time consuming, it is best for you to go through the Swift documentation from the beginning to fully understand it.

Reference:

As Hamish has pointed please read about closures, then auto closures from https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html

Upvotes: 5

Related Questions