表达式类型不明确,没有更多上下文错误源于两个事实:
- Swift 不知道如何添加
DispatchTime 和 Int。
- 由于事实 1,Swift 不知道如何解释
.now()。
Swift 不知道如何添加 DispatchTime 和 Int
这可以通过以下方式证明:
let t = DispatchTime.now() + Int(5)
二元运算符“+”不能应用于“DispatchTime”和“Int”类型的操作数
但 Swift 确实知道如何添加 DispatchTime 和 Double:
let t = DispatchTime.now() + Double(5)
编译正常,没有错误。
那么为什么DispatchQueue.main.asyncAfter(deadline: .now() + 5) 有效?
在这种情况下,Swift 将整数文字 5 解释为 Double。 Double 类型符合 ExpressibleByIntegerLiteral 协议,这是允许您执行的操作:
let d: Double = 5
所以在这种情况下,它可以工作,因为5 不是Int,而是Double。
由于事实 1,Swift 不知道如何解释 .now()
当您尝试将Int 添加到.now() 时:
DispatchQueue.main.asyncAfter(deadline: .now() + int)
Swift 类型推断系统变得混乱。 Swift 知道它想将DispatchTime 传递给asyncAfter(deadline:),但它不再能够弄清楚.now() 是什么,因为无法添加DispatchTime 和Int 来获得DispatchTime ,它决定 .now() 不是 DispatchTime 而是其他一些未知类型。因此,模棱两可的错误消息来自 Swift 无法确定 .now() 是什么。
如果你通过说 DispatchTime.now() 来明确表示,那么你会得到一个更明智的错误:
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + int)
二元运算符“+”不能应用于“DispatchTime”和“Int”类型的操作数
作为该理论的进一步证据,如果您为 Swift 提供一种添加 DispatchTime 和 Int 的方法,那么 Swift 会对您的原始代码感到满意:
func +(_ lhs: DispatchTime, _ rhs: Int) -> DispatchTime {
return lhs + .seconds(rhs)
}
那么.seconds() 是什么东西?以及它如何帮助解决错误?
有一个相关的enum 类型DispatchTimeInterval 有microseconds(Int)、milliseconds(Int)、nanoseconds(Int)、seconds(Int) 和never。 Swift 知道如何添加 DispatchTime 和 DispatchTimeInterval,因此 Swift 能够将 .seconds(int) 解释为 DispatchTimeInterval,然后允许它将 .now() 解释为 DispatchTime。
为什么 Swift 设计者选择让您将 Double 添加到 DispatchTime 而不是 Int?
你必须问他们。我怀疑他们选择Double 是出于方便(允许使用诸如2.5 之类的文字值),并且因为它允许您指定小于一秒的时间间隔。 Int 没有为您提供任何额外的功能(当然除了消除这个非常令人困惑的错误消息)。
结论
错误是因为您尝试将Int 添加到DispatchTime 从而混淆了Swift 的类型推断系统。
其他答案建议的修复:
-
使用Double。
或
使用DispatchTimeInterval enum 明确注意您的Int 代表什么。在你的情况下.seconds(int)。