【问题标题】:How can you initialize a struct with a closure parameter like this?如何使用这样的闭包参数初始化结构?
【发布时间】:2021-12-30 14:21:09
【问题描述】:

this question我今天看到它定义了一个结构Effect,它有一个属性run,它是一个带有通用参数的闭包:

struct Effect<T> {
    let run: (@escaping (T) -> Void) -> Void
}

然后示例代码创建一个Effect&lt;Int&gt; 的实例,并使用类似于尾随闭包语法的东西指定run 属性的闭包:

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

是什么使它合法?我希望需要在调用 init 方法时明确指定 run 参数:

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

任何一个版本都可以编译和工作。 Swift 中的什么使第一个版本合法?我不知道如何构建问题以便寻找答案。

【问题讨论】:

    标签: swift struct closures


    【解决方案1】:

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

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

    func myfunc(whatever: () -> ()) {}
    myfunc {}
    

    好的,但现在让我们让它成为一个静态方法:

    struct S {
        static func myfunc(whatever: () -> ()) {}
    }
    S.myfunc {}
    

    好的,但是init 一个静态方法——它只是一个静态方法,你可以省略它的名字:

    struct S {
        let whatever: () -> ()
    }
    S {} // meaning S.init {}
    

    【讨论】:

    • 嗯。我从来没有想过你可以在调用初始化程序时使用尾随闭包语法,但我想这是有道理的。
    • 很多很多内置库类型都使用它,我很惊讶你直到现在才注意到。当然 SwiftUI 完全依赖于这种东西。
    • 好吧,我从来没有完全理解 SwiftUI 用于创建 View 对象的语法,但现在它非常有意义。我太迟钝了。
    • ??????☀️?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-04
    • 1970-01-01
    相关资源
    最近更新 更多