闭包函数和函数之间的区别

时间:2017-05-21 10:07:07

标签: swift

我试图快速学习并且碰到了关闭但是我还有一个问题要问,无法在互联网上找到任何答案,我不确定是否在这里提问是合适的,但我真的需要一个答案。

说我们有以下课程

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()

我想知道

的区别

fCheckGender和cCheckGender我应该何时何地使用闭包

提前致谢!

P.S我故意使用void-> String ()->(String?) 我只想了解这种情况的不同之处。我很抱歉我的英文不好

2 个答案:

答案 0 :(得分:4)

关闭:

  • Closure是一段代码,将其视为未命名的函数。
  • 当一个闭包作为参数传递时,在函数内部的代码调用参数之前,不会对闭包进行求值。

自动关闭:

  • 自动闭包只是一个闭包,它将参数值与它一起打包。
  • 定义autoclosure时,闭包没有参数。

fCheckGendercCheckGender之间的差异:

  • fCheckGenderString 作为参数。
  • cCheckGender以闭包为参数。
  • 当调用cCheckGender时,闭包被传递一个参数,此时,闭包仅作为参数传递,闭包不会被执行。只有在函数内部使用closure参数时,才会执行闭包。

你所说的例子可能不是展示差异的最佳例子。

让我们考虑一个不同的例子:

实施例

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")

输出:

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

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

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

示例说明:

  • 在函数f1中,pValue是一个Int值。
  • 因此,当调用f1时,将评估添加
  • 在函数f2和f3中,pClosure是一个闭包。
  • 在函数内部调用之前,不会计算pClosure(闭包)。

注意:

  • 首先关注f3接受闭包作为参数。
  • 完全理解f3后,请检查f2
  • 自动关闭会在调用参数值并在以后使用它时捕获它们。

为什么以及何时需要传递闭包而不是值:

  • 可能存在一种情况,您希望将add的执行推迟到函数f2调用它的时间。
  • 可能存在一种情况,您在其中发出异步请求,并且您希望在请求完成时执行一段代码。在这种情况下,您可以传递一个闭包。 (闭包不必总是返回一个值,它是一个未命名的函数,因此它可以接受参数)

为什么以及何时需要自动关闭:

  • 如果您希望推迟执行add并同时捕获其参数的值。

建议:

  • 虽然耗费时间,但最好从一开始就仔细阅读Swift文档。

参考:

正如Hamish所指出的,请阅读关于闭包的内容,然后从https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html

自动关闭

答案 1 :(得分:0)

功能

  

在函数createUser中,firebase运行应用程序的后台,因此当用户输入登录应用程序的按钮时,将触发功能“ RegisteredButtonPressed”。   如果正确,则会触发用户在用户名和密码中指定的用户名和密码,然后触发registeredButtonPressed函数。该“完成”功能将被激活后,它将打印到控制台中。

     
    

我在闭包中编写了相同的代码概念。

  
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)")

}
}

关闭

将func关键字转换为闭包

  1. 删除func关键字和函数名称
  2. 在func开头之后将开头的花括号带入开头(在userid之后的“ func Completed”中:Int有一个花括号,因此请在第二个花括号开始之前将其放进去)。
  3. 用“ in”关键字替换
  4. 而不是调用完成的功能,请剪切代码上方的第3点并将其粘贴到firebase.creativeUser内部的完成处
  5. 删除完成参数以使其成为尾随闭包

    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)")
    
    }
    
    
    }
    
    }