我该如何修复此代码,以免出现错误:表达式类型不明确且没有更多上下文?
var int = 0
while int < 100 {
DispatchQueue.main.asyncAfter(deadline: .now() + int) { // change 2 to desired number of seconds
// do stuff
}
int += 1
}
该代码正在applicationDidEnterBackground的分派队列中运行,试图使文本到语音在后台工作。
答案 0 :(得分:3)
表达式类型是模棱两可的,没有更多上下文错误是由两个事实引起的:
DispatchTime
和Int
。.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()
和{ {1}}得到DispatchTime
,它决定Int
不是DispatchTime
而是其他未知类型。因此,模棱两可的错误消息来自Swift无法确定.now()
是什么。
如果您通过说DispatchTime
来使之明确,那么您将得到一个更明智的错误:
.now()
二进制运算符'+'不能应用于类型'DispatchTime'和'Int'的操作数
作为该理论的进一步证据,如果您为Swift提供一种添加DispatchTime.now()
和DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + int)
的方法,那么Swift会对您的原始代码感到满意:
DispatchTime
那么
Int
这是什么东西?以及如何帮助解决错误?
有一个相关的func +(_ lhs: DispatchTime, _ rhs: Int) -> DispatchTime {
return lhs + .seconds(rhs)
}
类型.seconds()
,具有案例enum
,DispatchTimeInterval
,microseconds(Int)
,milliseconds(Int)
和nanoseconds(Int)
。 Swift知道如何添加seconds(Int)
和never
,因此Swift可以将DispatchTime
解释为DispatchTimeInterval
,然后允许将.seconds(int)
解释为DispatchTimeInterval
。
Swift设计师为什么选择让您在
.now()
而不是DispatchTime
上添加Double
?
您必须问他们。我怀疑他们是出于方便的考虑而选择DispatchTime
(允许使用诸如Int
之类的文字值),并且因为它允许您指定小于一秒的时间间隔。 Double
没有给您任何额外的功能(当然是为了消除此非常混乱的错误消息)。
结论
该错误来自于您通过尝试向2.5
添加Int
来混淆Swift的类型推断系统的事实。
其他建议的修复方法:
使用Int
。
或
使用DispatchTime
Double
明确记下DispatchTimeInterval
代表什么。对于您的情况enum
。
答案 1 :(得分:2)
您需要使用 double 变量将其添加到case 0
中。
.now()
答案 2 :(得分:1)
您可以使用文字进行DispatchTime
数学
DispatchQueue.main.asyncAfter(deadline: .now() + 2)
但不带Int
变量,这就是模棱两可。有一个DispatchTimeInterval
枚举可以传递一个Int
变量
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(int))