Swift 4:无法将类型“(Void)-> Void”的值分配给类型“(()-> Void)?”

Posted

技术标签:

【中文标题】Swift 4:无法将类型“(Void)-> Void”的值分配给类型“(()-> Void)?”【英文标题】:Swift 4: Cannot assign value of type '(Void) -> Void' to type '(() -> Void)?' 【发布时间】:2018-07-27 09:38:00 【问题描述】:

我是 Swift-Universe 中的菜鸟,但我必须让应用程序运行 ;) 如果您能帮助我找到解决方案,那就太好了。提前非常感谢。

升级到较新版本的 X-Code(版本 9.4.1)和 Swift 4 后会出现问题。

private var stoppedSuccessfully: (() -> Void)?

func stopRecording() -> Promise<Void> 

    return Promise  success, _ in

        self.stoppedSuccessfully = success // The error occors here: Cannot assign value of type '(Void) -> Void' to type '(() -> Void)?'


        if WCSession.default.isReachable 
            logger.info("Watch is reachable - Send Stop recording message.")
            let command = RecordingCommand.stop

            self.sendMessage(command, EvomoWatchConnectivityCore.WatchConnectivityCoreMethod.transferUserInfo,
                             nil, nil)

            // Create a Timeout
            let timeoutDelay: Double = 15

            DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + timeoutDelay) 

                if self.stoppedSuccessfully != nil 
                    self.logger.warning("### Stopped waiting for Apple Watch recording by Timeout!")
                    success(Void())
                    self.stoppedSuccessfully = nil
                

            

            return
        

        success(Void())
        self.stoppedSuccessfully = nil

    



// In a other part of the code:
self.stoppedSuccessfully?()
self.stoppedSuccessfully = nil

【问题讨论】:

为什么要将成功块存储在变量中? 这段代码不是我写的。所以我无法回答你的问题。 我认为您也应该将库更新为 swift 4(包含 Promise 的内容)。 【参考方案1】:

首先将stoppedSuccessfully的类型从(() -&gt; Void)?改为((Void) -&gt; Void)?

private var stoppedSuccessfully: ((Void) -> Void)?

因为,当您使用Promise&lt;T&gt; 时,传递给success 的闭包类型是(T)-&gt;Void 类型。在您的代码中,您使用的是Promise&lt;Void&gt;,因此success 的类型是(Void)-&gt;Void,而不是()-&gt;Void

因此,您的stoppedSuccessfully 应声明为Optional&lt;(Void)-&gt;Void&gt;,相当于((Void)-&gt;Void)?


要调用(Void)-&gt;Void 类型的闭包,您需要传递一个Void 类型的参数。有一个 Void 类型的字面符号,它是 (),一个空元组。

因此,您可以将所有 success(Void())s 替换为简单的 success(())

你可以用类似的方式调用stoppedSuccessfully

// In a other part of the code:
self.stoppedSuccessfully?(())

【讨论】:

非常感谢您的回答。这很好用! @Prashant 的答案也有效,但这个解决方案更干净。【参考方案2】:

不需要使用Void 只需使用stoppedSuccessfully: ((Void) -&gt; ())? 并使用

 let obj:Void = Void()
 stoppedSuccessfully?(obj) 

我不明白你为什么使用stoppedSuccessfully 它不一定是从success 分配的,它永远不会是nil 所以不要认为你的条件if self.stoppedSuccessfully != nil 会失败

【讨论】:

感谢您的回答!如果我按照您提到的那样更改变量声明。 X-Code 在“self.stoppedSuccessfully = success”行返回以下错误消息:无法将类型 '(Void) -> Void' 的值分配给类型 '(() -> ())?'。我没有写这段代码。所以我不知道条件是否会失败。但我知道该代码以前在 Swift 3 中有效。 @JayUU 检查已成功停止:((Void) -> ())? 这解决了“self.stoppedSuccessfully = success”行中的错误,但在“self.stoppedSuccessfully?()”行中创建了一个新错误。 -> 调用中参数#1 缺少参数 @JayUU 这不是正确的方法,但它会起作用let obj:Void = Void() stoppedSuccessfully?(obj) 你才是男人!!!它正在工作。非常感谢!如果您更改/扩展您的答案,我可以将其标记为已解决...

以上是关于Swift 4:无法将类型“(Void)-> Void”的值分配给类型“(()-> Void)?”的主要内容,如果未能解决你的问题,请参考以下文章

更新 PromiseKit 后出错:无法将“PMKFinalizer”类型的值转换为预期的参数类型“Promise<Void>”

swift 4.2 无法将类型“(_)-> Void”的值转换为预期的参数类型“(()-> Void)?”

Swift 4.1 - 无法将 [Character] 类型的值转换为 [String]

无法转换任何类型?要键入 AnyObject?从 swift 3 转换为 swift 4 时

SWIFT 4.1 无法使用类型为“(字符串?)”的参数列表调用类型“Double”的初始化程序

Swift2.1keyword @noescape介绍