Тип выражения неоднозначен без контекста. * Ошибка 1002 * обусловлена двумя фактами:
- Swift не знает, как добавить
DispatchTime
и * 1007.*. - Из-за факта 1 Свифт не знает, как интерпретировать
.now()
.
Свифт не знает, как добавить 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 Свифт не знает, как интерпретировать .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
не дает вам никаких дополнительных возможностей (за исключением, конечно, устранения этого очень запутанного сообщения об ошибке).
Заключение
Ошибка исходит оттот факт, что вы запутали систему вывода типов Swift, пытаясь добавить Int
к DispatchTime
.
Исправления, как предлагали другие ответы:
ИспользоватьDouble
.
или
Используйте DispatchTimeInterval
enum
, чтобы явно отметить, что представляет собой Int
.В вашем случае .seconds(int)
.