可以设定同类型的参数为可变个数,然后在函数里将该参数作为数组来使用。 可变参数的位置不一定是最后一个。
示例代码:
func manyVar(v : Int..., d : Double) {
for i in v { //作为数组使用
}
}
manyVar( d: 2.2) //传 0 个v参数
manyVar(v:1,2,3, d: 2.2) //传3个 v参数
Block 和 函数在使用它们外部的变量时,使用的是该变量的引用(无论是基本类型还是 类结构),当变量变化时,block和函数内部的该变量也会一起变化。
代码例子:
var bInt : Int = 4
func capture(_ num : Int) -> String {
bInt += num
return "caturpe \(bInt)"
}
bInt += 1
print("capture \(capture(1))”) //打印 capture 6
print("capture \(capture(2))”) //打印 capture 7, 此时 bInt 变成7了
当闭包作为函数最后一个参数时,可以将闭包体放在函数的括号外面,这是一个语法糖。
代码例子:
func someFunctionThatTakesAClosure(closure: () -> Void) {
// 函数体部分
}
someFunctionThatTakesAClosure({
//闭包体
})
someFunctionThatTakesAClosure() {
//闭包体
}
在闭包体内,可以用 $0 下标来获取对应的位置的参数。 代码例子:
let sort : (Int, Int) -> Bool = { $0 > $1 }
[1,2,3].sorted(by: sort)
可以改写特定类型数据(对象)的运算符行为。
样例代码:
class EqualClass : Equatable {
var value : Int = 2
init(v : Int) {
value = v
}
static func == (o1 : EqualClass, o2 : EqualClass) -> Bool {
return o1.value == o2.value
}
static func > (o1 : EqualClass, o2 : EqualClass) -> Bool {
return o1.value > o2.value
}
}
逃逸闭包:闭包有可能在函数结束后调用,闭包调用逃离了函数的作用域,需要通过@escaping声明。 比如下面例子,传入的闭包用对象属性保存了下来,可能在任意时间被调用。
class SwiftClosure : SwiftTestProtocol {
typealias emptyClosure = () -> ()
var callback :emptyClosure? = nil
func setCallback(_ call : @escaping emptyClosure) {
self.callback = call
}
func main() {
self.setCallback {
print("my callback")
}
}
}
逃逸闭包里不能使用外面的 inout 参数。
func modifyInt(_ value : inout Int) {
self.setCallback { [weak self] in
value += 4 //编译报错
print("my callback")
}
self.callback!()
self.callback!()
}