如何使用这样的闭包参数初始化结构体?

Dun*_*n C 4 struct closures swift

在这个问题中,我今天看到它定义了一个结构体Effect,该结构体具有一个属性run,该属性是一个采用通用参数的闭包:

struct Effect<T> {
    let run: (@escaping (T) -> Void) -> Void
}
Run Code Online (Sandbox Code Playgroud)

然后示例代码创建 的实例,并使用类似于尾随闭包语法的内容Effect<Int>指定属性的闭包:run

let anIntInTwoSeconds = Effect<Int> { callback in
    DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
        callback(42)
    }
}
Run Code Online (Sandbox Code Playgroud)

是什么让这合法?我希望需要在调用 init 方法时显式指定运行参数:

let anIntInTwoSeconds = Effect<Int>(run: { callback in
    DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
        callback(42)
    }
}
)
Run Code Online (Sandbox Code Playgroud)

任一版本均可编译并运行。Swift 中的什么使第一个版本合法?我不知道如何提出这个问题以便我可以寻找答案。

mat*_*att 9

这就像任何最后一个参数是函数的函数一样。尾随闭包语法是尾随闭包语法。该函数是一个初始化器这一事实没有改变。

\n

所以让我分阶段进行。你知道你可以说:

\n
func myfunc(whatever: () -> ()) {}\nmyfunc {}\n
Run Code Online (Sandbox Code Playgroud)\n

好的,但现在让我们将其设为静态方法:

\n
struct S {\n    static func myfunc(whatever: () -> ()) {}\n}\nS.myfunc {}\n
Run Code Online (Sandbox Code Playgroud)\n

好的,但它init 是一个静态方法 \xe2\x80\x94 它只是一个静态方法,您可以省略其名称:

\n
struct S {\n    let whatever: () -> ()\n}\nS {} // meaning S.init {}\n
Run Code Online (Sandbox Code Playgroud)\n

  • 很多很多内置库类型都使用它,我很惊讶你直到现在才注意到。当然,SwiftUI 完全依赖于这种东西。 (2认同)