本文主要是介绍IOS Swift 从入门到精通:闭包第二部分,高级闭包,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- 当闭包接受参数时使用闭包作为参数
- 当闭包返回值时使用闭包作为参数
- 简写参数名称
- 高级闭包: 具有多个参数的闭包
- 高级闭包:从函数返回闭包
- 高级闭包:捕获值
- 总结
当闭包接受参数时使用闭包作为参数
这是闭包开始变得有点像线路噪声的地方:传递给函数的闭包也可以接受它自己的参数。
我们一直使用() -> Void它来表示“不接受任何参数并且不返回任何内容”,但是您可以继续填充()闭包应该接受的任何参数的类型。
为了证明这一点,我们可以编写一个travel()接受闭包作为其唯一参数的函数,并且该闭包又接受一个字符串:
func travel(action: (String) -> Void) {print("I'm getting ready to go.")action("London")print("I arrived!")
}
现在,当我们travel()使用尾随闭包语法调用时,我们的闭包代码需要接受一个字符串:
travel { (place: String) inprint("I'm going to \(place) in my car") }
当闭包返回值时使用闭包作为参数
我们一直使用() -> Void它来表示“不接受任何参数并且不返回任何内容”,但是您可以Void用任何类型的数据替换它以强制闭包返回一个值。
为了证明这一点,我们可以编写一个travel()接受闭包作为其唯一参数的函数,而该闭包又接受一个字符串并返回一个字符串:
func travel(action: (String) -> String) {print("I'm getting ready to go.")let description = action("London")print(description)print("I arrived!")
}
现在,当我们travel()使用尾随闭包语法调用时,我们的闭包代码需要接受一个字符串并返回一个字符串:
travel { (place: String) -> String inreturn "I'm going to \(place) in my car"
}
简写参数名称
我们刚刚创建了一个travel()函数。它接受一个参数,这是一个闭包,它本身接受一个参数并返回一个字符串。然后该闭包在两次调用之间运行print()。
代码如下:
func travel(action: (String) -> String) {print("I'm getting ready to go.")let description = action("London")print(description)print("I arrived!")
}
我们可以travel()使用如下方法调用:
travel { (place: String) -> String inreturn "I'm going to \(place) in my car"
}
但是,Swift知道该闭包的参数必须是字符串,因此我们可以将其删除:
travel { place -> String inreturn "I'm going to \(place) in my car"
}
它还知道闭包必须返回一个字符串,所以我们可以删除它:
travel { place inreturn "I'm going to \(place) in my car"
}
由于闭包只有一行代码,并且必须是返回值的代码,所以 Swiftreturn也允许我们删除关键字:
travel { place in"I'm going to \(place) in my car"
}
Swift 有一个简写语法,可以让你写得更简洁。我们可以让 Swift 自动为闭包的参数提供名称,而不是直接书写place in。这些参数以美元符号命名,然后是一个从 0 开始的数字。
travel {"I'm going to \($0) in my car"
}
高级闭包: 具有多个参数的闭包
为了确保一切都清楚,我们将使用两个参数编写另一个闭包示例。
这次我们的travel()函数需要一个闭包来指定某人要去的地方以及他们要行驶的速度。这意味着我们需要使用(String, Int) -> String参数的类型:
func travel(action: (String, Int) -> String) {print("I'm getting ready to go.")let description = action("London", 60)print(description)print("I arrived!")
}
我们将使用尾随闭包和简写闭包参数名称来调用它。因为这接受两个参数,所以我们将同时获取$0和$1:
travel {"I'm going to \($0) at \($1) miles per hour."
}
有些人不喜欢使用简写参数名称,$0因为它可能会造成混淆,但这没关系 - 只要对您来说最有效就行。
高级闭包:从函数返回闭包
就像你可以将闭包传递给函数一样,你也可以从函数获取返回的闭包。
这个语法首先有点令人困惑,因为它使用了->两次:一次用于指定函数的返回值,第二次用于指定闭包的返回值。
为了尝试这一点,我们将编写一个travel()不接受任何参数但返回闭包的函数。返回的闭包必须使用字符串调用,并且不会返回任何内容。
在 Swift 中它看起来是这样的:
func travel() -> (String) -> Void {return {print("I'm going to \($0)")}
}
我们现在可以调用travel()来取回该闭包,然后将其作为函数调用:
let result = travel()
result("London")
从技术上讲,直接调用返回值是允许的(尽管并不推荐!)travel():
let result2 = travel()("London")
高级闭包:捕获值
如果在闭包中使用任何外部值,Swift会捕获它们 - 将它们与闭包一起存储,这样即使它们不再存在也可以对其进行修改。
现在我们有一个travel()返回闭包的函数,返回的闭包接受一个字符串作为其唯一参数并且不返回任何内容:
func travel() -> (String) -> Void {return {print("I'm going to \($0)")}
}
我们可以调用travel()来取回闭包,然后自由地调用该闭包:
let result = travel()
result("London")
如果我们创建在travel()闭包内部使用的值,就会发生闭包捕获。例如,我们可能想要跟踪返回的闭包被调用的频率:
func travel() -> (String) -> Void {var counter = 1return {print("\(counter). I'm going to \($0)")counter += 1}
}
即使该counter变量是在内部创建的travel(),它也会被闭包捕获,因此它仍然会对该闭包保持有效。
因此,如果我们result(“London”)多次调用,计数器就会不断增加:
result("London")
result("London")
result("London")
总结
- 您可以将闭包分配给变量,然后稍后调用它们。
- 闭包可以接受参数并返回值,就像常规函数一样。
- 您可以将闭包作为参数传递给函数,并且这些闭包可以具有自己的参数和返回值。
- 如果函数的最后一个参数是闭包,则可以使用尾随闭包语法。
- $0Swift 自动提供像和 这样的简写参数名称$1,但并不是每个人都使用它们。
- 如果在闭包内部使用外部值,它们将被捕获,以便闭包稍后可以引用它们。
这篇关于IOS Swift 从入门到精通:闭包第二部分,高级闭包的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!