功能快捷:关于关闭
有人说,函数和闭包是同一事物,具有不同的语法。 其他人则说函数是一种特殊的闭包。
闭包是一流的对象,因此它们可以嵌套并传递
首先,让我们知道一个函数是什么:
功能:
您可以使用func
关键字定义一个函数。 函数可以接受多个参数,不返回任何一个或多个参数( 使用元组 ,我们一次可以返回多个值)。
上面的函数将两个整数作为输入,并返回一个带有两个整数值的元组。 如果您没有使用元组的经验,请在此处查看我的其他文章。
功能类型
让我们考虑一个简单的函数,该函数需要一个int
并返回一个int
。
func doSometingWithInt(someInt:Int)-> Int { return someInt * 2 }
每个函数都有其自己的函数类型,该函数类型由参数类型和函数本身的返回类型组成。 上述函数的函数类型为:
(int)->(int)
如果函数接受两个参数并返回一个参数,则类型为:
(int,int)->(int)
此函数类型可用作嵌套函数的返回类型或用作参数。
func personInTheHouse()->((String)-> String){ func doProcess(process:String)->(String){//嵌套函数 return“此人是\(process)。” } return doProcess //或return doProcess(process :) } let person = personInTheHouse() print(person(“打板球”))//打印“ 此人正在打板球。 ”
定义一个闭包:
了解闭包语法非常容易。 您现在知道什么是function type
。 只需将函数类型放在一对花括号中,然后在返回类型后面添加一个in
关键字。 in
关键字后跟语句。 它成为闭包表达式。
{(参数)-> 语句中的 returnType }
闭包表达式是用轻量级语法编写的未命名的闭包,可以从其周围的上下文中捕获值。 闭包表达式语法在上面的代码块中给出。
- 闭包表达式提供了几种语法优化,以简化形式编写闭包,而不会造成清晰度或意图的损失。
- 闭包表达式语法中的参数可以是in-out参数,但不能具有默认值。 如果您命名可变参数,则可以使用可变参数。 元组也可用作参数类型和返回类型。
让我们创建一个接受两个int
值并将其和返回为int
的函数。
func addTwoNumbers(number1:Int,number2:Int)-> Int { 返回number1 + number2 } addTwoNumbers(number1:8,number2:2)//结果为10
现在让我们为同一操作创建一个闭包:
让闭包:(Int,Int)-> Int = {(number1,number2)in return number1 + number2 } Closure(8,2)//结果为10
函数和闭包在代码行数,可读性等方面看起来或多或少相似。让我们尝试简化闭包甚至更简单。
速记参数名称
闭包参数可以按位置($ 0,$ 1,…)而不是名称进行引用。
var shortHandClosure:(Int,Int)-> Int = { return $ 0 + $ 1 } shortHandClosure(8,2)//结果为10
由于,闭包的主体包含返回Int
值的单个表达式,因此我们可以省略return
语句。 如果闭包体内有多行代码,那么我们就不能省略return语句。
var superShortClosure:(Int,Int)-> Int = {$ 0 + $ 1}
现在,这看起来与我们一开始定义的功能有很大不同。 这也更加简单和有意义。
注意:如果必须与return表达式一起编写其他
我们的目标是编写更少的代码。
推断类型的关闭
在以下代码中推断类型为(Int,Int)->Int
的闭包:
let inferredClosure = {(x:Int,y:Int)-> Int in x + y} inferredClosure(1,99)//结果为100
还可以推断出返回类型:
让inferredReturnTypeClosure = {{number:Int)in number * number}
您期望上述闭包的类型是什么?,它返回一个int
。
它是(Int) -> Int
不带任何内容并返回字符串的闭包:
闭包可以是() -> (SomeType)
。
以下是不带任何参数并返回字符串的闭包。
让callStringWtihClosure:()-> String = {() 返回“ hello” } // ____________ print(callStringWtihClosure())//打印“ hello”
由于我们在这里不关心输入参数,因此可以在闭包体内省略() in
。
下面的一种关闭类型为() -> String
let callStringWtihClosure:()-> String = {返回“ hello”}
另外,由于它返回String
且不带任何参数,因此我们也可以省略类型。
下面的一种关闭类型为() -> String
让callStringWithClosureWithoutType = {“嗨,我也是闭包”}
闭包和函数是迅速的一流类型:
函数和闭包是Swift中的一等公民,因为您可以将其视为普通值。 例如,您可以…
- 将函数/闭包分配给局部变量。
- 传递函数/闭包作为参数。
- 返回一个函数/闭包。
使用闭包完成回调的方法:
这是我的关于使用闭包完成回调的方法的文章。 读这个。
以下代码具有一个包含三个参数的函数。 一个是字典,另外两个是闭包,当过程完成后,它们将充当回调函数。
在此处阅读有关闭包的更多信息 。
自动关闭
自动闭包是一种自动创建的闭包,用于包装将作为参数传递给函数的表达式。 它不带任何参数,并且在调用它时,它返回包装在其中的表达式的值。 这种语法上的便利性使您可以通过编写正则表达式而不是显式闭包来省略函数参数的花括号。
过度使用自动关闭功能会使您的代码难以理解。
var customerInLine = [“ Chris”,“ Alex”,“ Ewa”,“ Barry”,“ Daniella”] print(customersInLine.count) //打印“ 5” let customerProvider = {customersInLine.remove(at:0)} / /这是类型()-> String print(customerProvider())//打印Chris .. remove(at :)返回一个String。
考虑将上面的函数作为参数传递给函数。
// customersInLine is ["Alex", "Ewa", "Barry", "Daniella"]
func serve(customer customerProvider: () -> String) {
print("Now serving \(customerProvider())!")
}
serve(customer: { customersInLine.remove(at: 0) } ) // we cannot omit {}
// Prints "Now serving Alex!"
上面清单中的serve(customer:)
函数采用显式闭包,返回客户的姓名。 下面的serve(customer:)
版本执行相同的操作,但不进行显式关闭,而是通过使用@autoclosure
属性标记其参数类型来进行自动@autoclosure
。 现在,您可以像调用String
参数而不是使用闭包一样调用该函数。 该参数将自动转换为闭包,因为customerProvider
参数的类型已用@autoclosure
属性标记。
// customersInLine is ["Ewa", "Barry", "Daniella"]
func serve(customer customerProvider: @autoclosure () -> String) {
print("Now serving \(customerProvider())!")
}
serve(customer: customersInLine.remove(at: 0))
// Prints "Now serving Ewa!"
如果要允许自动转义可以转义,请同时使用
@autoclosure
和@escaping
属性。
简而言之,
serve(customer: { customersInLine.remove(at: 0) }) // need {}
变成…..
serve(customer: customersInLine.remove(at: 0)) // omit {}
解释自动关闭的另一个示例:
我们可以在UIView
上创建扩展,并添加以下内容:
extension UIView { class func animate(withDuration duration: TimeInterval, _ animations: @escaping @autoclosure () -> Void) { UIView.animate(withDuration: duration, animations: animations) } }
以便,
UIView.animate(withDuration: 2.5) { self.view.backgroundColor = .orange }
变成…。
UIView.animate(withDuration: 2.5, self.view.backgroundColor = .orange)
最后但是同样重要的!!!
函数和闭包是引用类型 。 在这里,在以下代码中,
addClosure2
和addClosure
引用内存中的同一关闭。
var addClosure:(Int,Int)-> Int = {$ 0 + $ 1} 让addClosure2 = addClosure
请享用!!
如果您喜欢阅读这篇文章,请分享并推荐它,以便其他人可以找到💚💚💚💚💚💚!!!!
您可以在Medium上关注我以获取新文章。 在LinkedIn上与我联系。
如果您有任何评论,问题或建议,请随时在下面的评论部分中发布它们!