闭包(closures)
-
与
OC中的block类似 -
优势
- 闭包体只有一行代码,可以省略
return $0,$1表示第i个参数- 提供了尾随闭包语法(
trailing closure syntax)
- 闭包体只有一行代码,可以省略
-
定义和使用
参数、返回值和in都可以省略 let studname = { print("swift 闭包") } studname() let divide = { (val: Int, val2: Int) -> Int in return val * val2 } let result = divide(200,20) -
sorted// 原数组不会被改变,返回新数组 var reversed = name.sorted(by: backward(s1:s2:)) // 通过参数缩写来调用闭包的参数 var reversed1 = name.sorted(by: {$0 > $1}) // 运算符函数,string类型定义了关于大于号(>)的字符串实现,其作为一个函数接收两个String并返回Bool, 与sorted方法的第二个参数函数类型符合 var reversed2 = name.sorted(by: >) // 使用尾随闭包 let reversed3 = name.sorted(){$0 > $1} -
尾随闭包
- 书写在函数括号之后的闭包
func someMethod(closure: () -> Void) { print("someMethod") closure() } // 不使用尾随闭包进行函数调用 someMethod (closure: { print("test") }) // 以下是使用尾随闭包进行函数调用 someMethod () { print("test1") } // 如果函数只需要闭包表达式一个参数,当使用闭包时,可以把()省略掉 someMethod { print("test1") } -
捕获值
func someMethod(amount : Int) -> ()->Int { var runningToatal = 0 func incrementor() -> Int { //runningToatal 的原来的作用域已经不存在,闭包仍然可以再闭包函数体内引用和修改这些值,会存储捕获的值的副本 runningToatal += amount return runningToatal } return incrementor } let temp = someMethod(amount: 10) temp() // 输出10 temp() // 输出20无论您将函数/闭包赋值给一个常量还是变量,您实际上都是将常量/变量的值设置为对应函数/闭包的引用。 上面的例子中,incrementByTen指向闭包的引用是一个常量,而并非闭包内容本身。
-
闭包是引用类型
- 函数也是引用类型
func someMethod(amount : Int) -> ()->Int { var runningToatal = 0 func incrementor() -> Int { //runningToatal 的原来的作用域已经不存在,闭包仍然可以再闭包函数体内引用和修改这些值,会存储捕获的值的副本 runningToatal += amount return runningToatal } return incrementor } let temp = someMethod(amount: 10) temp() // 输出10 temp() // 输出20
- 函数也是引用类型
函数
- 一般函数
func someMethod() -> Int { return 0 } someMethod() - 返回元组的函数
func someMethod(array: [Int]) -> (min: Int, max: Int) { var currentMin = array[0] var currentMax = array[1] for value in array { if value < currentMin { currentMin = value } else if value > currentMax { currentMax = value } } return (currentMin, currentMax) - 局部参数和外部函数-如果提供了外部参数名,函数调用时,则必须使用外部参数名
func powTest (firstArg a: Int, second b: Int) -> Int { var res = a for _ in 1...b { res = res * a } return res } powTest(firstArg: 1, second: 2) - 可变参数
可以接受0个或者多个参数,可变参数通过在类型名称后面增加(...) 来定义 func vari<N>(menmbers: N...) { for i in menmbers { print(i) } } I/O参数在参数定义前加inout 关键字,就可以改变这个参数的值 func swapTwoInts(a: inout Int, b: inout Int) { let temp = a a = b b = temp } var x = 1 var y = 2 swapTwoInts(a: &x, b: &y)- 函数的类型---由函数的参数类型和返回值类型组成
func sum(a: Int, b: Int) -> Int { return a + b } // 定义一个叫addition变量,参数和返回值都是Int,并让这个新变量指向sum函数 var addition: (Int,Int) -> Int = sum // 函数类型作为参数类型、作为返回值类型 func another(addition: (Int, Int) -> Int, a: Int, b: Int) ->Int { addition(a,b) } another(addition: sum, a: 12, b: 8) - 函数嵌套
函数内定义一个新的函数,外部可以调用函数内定义的函数 func calcDecrement(forDecrement total: Int)-> () -> Int { var overallDecrement = 0 func decrementer() -> Int { overallDecrement -= total return overallDecrement } return decrementer } let decrem = calcDecrement(forDecrement: 30) print(decrem())