表达式类型不明确,没有更多上下文错误

D-A*_* UK 2 xcode ios swift dispatch-queue

如何修复此代码,使其不会出现错误:没有更多上下文的表达式类型不明确?

var int = 0
while int < 100 {
        DispatchQueue.main.asyncAfter(deadline: .now() + int) { // change 2 to desired number of seconds
            // do stuff
        }
        int += 1
}
Run Code Online (Sandbox Code Playgroud)

该代码正在 applicationDidEnterBackground 的调度队列中运行,以尝试在后台进行文本到语音的工作。

vac*_*ama 8

表达式的类型是模糊的没有更多的情况下错误是由两个事实而产生:

  1. Swift 不知道如何添加 aDispatchTimeInt
  2. 由于事实 1,Swift 不知道如何解释.now().

Swift 不知道如何添加一个DispatchTime和一个Int

这可以通过以下方式证明:

let t = DispatchTime.now() + Int(5)
Run Code Online (Sandbox Code Playgroud)

二元运算符“+”不能应用于“DispatchTime”和“Int”类型的操作数

但 Swift 确实知道如何添加 aDispatchTime和 a Double

let t = DispatchTime.now() + Double(5)
Run Code Online (Sandbox Code Playgroud)

这编译得很好,没有错误。

那么为什么DispatchQueue.main.asyncAfter(deadline: .now() + 5)有效呢?

在这种情况下,Swift 将整数文字解释5Double. 类型Double符合ExpressibleByIntegerLiteral允许您执行以下操作的协议:

let d: Double = 5
Run Code Online (Sandbox Code Playgroud)

所以在这种情况下,它有效,因为5不是Int,而是Double

因为事实 1,Swift 不知道如何解释 .now()

当您尝试添加Intto 时.now()

DispatchQueue.main.asyncAfter(deadline: .now() + int)
Run Code Online (Sandbox Code Playgroud)

Swift 类型推断系统被搞糊涂了。Swift 知道它想将 a 传递DispatchTimeasyncAfter(deadline:),但它不再弄清楚是什么.now(),因为无法添加 aDispatchTime和 anInt来获取 a DispatchTime,它决定那.now()不是 aDispatchTime而是其他未知类型。所以模棱两可的错误消息来自 Swift 无法确定是什么.now()

如果你通过说 明确表示DispatchTime.now(),那么你会得到一个更明智的错误:

DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + int)
Run Code Online (Sandbox Code Playgroud)

二元运算符“+”不能应用于“DispatchTime”和“Int”类型的操作数

作为这个理论的进一步证据,如果你为 Swift 提供一种添加 aDispatchTime和 an 的方法Int,Swift会对你的原始代码感到满意:

func +(_ lhs: DispatchTime, _ rhs: Int) -> DispatchTime {
    return lhs + .seconds(rhs)
}
Run Code Online (Sandbox Code Playgroud)

那么这个.seconds()东西是什么呢?它如何帮助解决错误?

还有一个相关的enum类型DispatchTimeInterval有案件microseconds(Int)milliseconds(Int)nanoseconds(Int)seconds(Int)never。Swift 知道如何添加 aDispatchTime和 a DispatchTimeInterval,因此 Swift 能够解释.seconds(int)为 aDispatchTimeInterval然后允许它解释.now()为 a DispatchTime

为什么 Swift 设计者选择让你在 aDouble中添加aDispatchTime而不是 an Int

你得问他们。我怀疑他们选择Double了方便(允许2.5使用诸如文字值)并且因为它允许您指定小于一秒的时间间隔。在Int不给你任何其他的功能(当然除了为消除这种非常混乱的错误消息)。

结论

错误来自于您试图将 an 添加IntDispatchTime.

其他答案建议的修复:

  1. 使用一个Double.

    或者

  2. 使用DispatchTimeInterval enum来明确说明您所Int代表的内容。在你的情况下.seconds(int)