在参数传递时编译Swift 4中的错误

yaa*_*ali 11 swift swift4 ios11 xcode9-beta

我在Xcode 9 Beta 3中使用了第三方库.我在完成调用中收到以下错误,我无法解决此错误:

DispatchQueue.main.asyncAfter(deadline: .now() + delay) { 
    self.animationView?.alpha = 0
    self.containerView.alpha  = 1
    completion?()    // -> Error: Missing argument parameter #1 in call.   
}
Run Code Online (Sandbox Code Playgroud)

并在完成功能中获得以下警告:

func openAnimation(_ completion: ((Void) -> Void)?) {    
    // -> Warning: When calling this function in Swift 4 or later, you must pass a '()' tuple; did you mean for the input type to be '()'?
}    
Run Code Online (Sandbox Code Playgroud)

OOP*_*Per 22

在Swift 4中,元组的处理比以往更加严格.

这种封闭类型:(Void)->Void意味着封闭

  • 采用一个参数,其类型是 Void
  • 返回Void,意味着不返回任何值

因此,请尝试以下任何一项:

将值的值传递Void给闭包.(空元组()是唯一的实例Void.)

completion?(())
Run Code Online (Sandbox Code Playgroud)

要不然:

更改参数的类型completion.

func openAnimation(_ completion: (() -> Void)?) {
    //...
}
Run Code Online (Sandbox Code Playgroud)

请记住,两种类型的(Void)->Void()->Void甚至在斯威夫特3.不同的,所以后者将是适当的,如果你打算代表不带参数的闭合型.

此更改是SE-0029的一部分从函数应用程序中删除隐式元组splat行为,据说在Swift 3中实现,但似乎Swift 3尚未完全实现它.


在这里,我向您展示了一个简化的检查代码,您可以在Playground上查看差异.

import Foundation

//### Compiles in Swift 3, error and warning in Swift 4
class MyClass3 {

    func openAnimation(_ completion: ((Void) -> Void)?) {
        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {

            completion?()
        }
    }

}

//### Compiles both in Swift 3 & 4
class MyClass4 {

    func openAnimation(_ completion: (() -> Void)?) {
        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {

            completion?()
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

  • 它现在工作正常。不知道为什么有时编译器会出错,有时运行没有任何问题。 (2认同)