Xcode尾随闭包报错:Extra trailing closure passed in call
Xcode尾随闭包报错:Extra trailing closure passed in call

Xcode尾随闭包报错:Extra trailing closure passed in call

问题描述

在传递闭包视图时,发现传递闭包的代码报错。

ContentView视图中,在传递CardView视图闭包时,提示报错。

报错代码为

CardView(card: cards[index]) {
    withAnimation {
        removeCard(at: index)
    }
}

报错内容为

Extra trailing closure passed in call

在CardView视图中,实际上是有闭包属性的:

struct CardView: View {
    @State private var isShowingAnswer = false
    @State private var offset = CGSize.zero
    var removal: (() -> Void)? = nil
    let card: Card

    var body: some View {
        ...
    }
}

排查和解决

起初以为是闭包在ContentView的环境内,因为某些原因导致无法解决。

然后改为手动包裹CardView的removal闭包:

CardView(card: cards[index], removal: {
    withAnimation {
        removeCard(at: index)
    }
})

修改后仍然报错,报错代码为:

Argument 'removal' must precede argument 'card'
Replace 'card: cards[index], removal: {
    withAnimation {
        removeCard(at: index)
    }
}' with 'removal: {
    withAnimation {
        removeCard(at: index)
    }
}, card: cards[index]'

这个报错表示参数“removal”必须位于参数“card”之前。这时我就知道尾随闭包不能正常使用的原因为,闭包参数在CardView视图中,应该在最后一位。

因此,解决方案为,保持ContentView中的CardView代码不动:

CardView(card: cards[index]) {
    withAnimation {
        removeCard(at: index)
    }
}

将CardView视图中的闭包参数removal调到最后的位置。

重新运行后,问题得到解决。

结论为:在 Swift 中,尾随闭包(trailing closure)的确要求闭包类型的参数位于方法或初始化器的最后一个位置。这是 Swift 的语法规则,因为尾随闭包的设计是为了简化代码语法,让闭包的使用更加直观。

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开放者。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注