Skip to main content
你呀你,是自在如风的少年 ♬

在 Swift 中如何定义 Closures

·190 words·1 min· 👀

在 ObjC 中如何定义 Block 中总结了 OC 中 block 的语法。

不知道 Swift 有没有类似 fuckingblocksyntax.com 的网站,反正我这篇是叫 fucking-closures-syntax 😬

使用方法 #

{ (parameters) -> returnType in
    statements
}

局部变量 #

语法定义
var closureName : (parameters) -> returnType = {
    (parameters) -> returnType in
    // statements
}

例如:

let handler : (Float) -> Void = {
    (_ arg: Float) -> Void in
    print(arg)
}

// 这里参数类型可以省略
let handler : (Float) -> Void = {
    arg in
    print(arg)
}

// 如果闭包内只有一个表达式,return 也可以省略
var completion : ((Float) -> Int)? = {
    Int($0) * 2
}

属性 #

语法定义
var closureName : (parameters) -> returnType

例如:

var defaultHandler : () -> Void = {
    print("Hello Closures.")
}

我们有时候需要定义一个可能为空的闭包,那么可以使用可选值。

var handler : ((Float) -> Void)?

// 在使用时更安全,不需要额外判空
self.handler?(2.0)

方法参数 #

func methodA(closure: () -> Void) {
    closure()
}

func methodB(closure: (_ a : Float) -> Void) {
    closure(3.0)
}

func methodC(closure: (_ a : Float) -> Void, arg: Int) {
    closure(3.0)
}

函数调用 #

对于上述参数是闭包的方法,调用时,我们可以忽略一些细节。

  • 如闭包是函数最后一个参数,可以直接忽略实参标签
  • 可以用 $0 $1 代替闭包的实参,避免写 arg in
  • 对于操作类闭包,甚至可以省略到只保留操作符
self.methodA {
    print(2.0)
}

self.methodB {
    print($0)
}

self.methodC(closure: { a in
    print(a)
}, arg: 0)

typealias #

typealias CompletionHandler = ((Float) -> Int)?