Свист. Путь над моей головой. Думаю, мне придется посмотреть это видео WWDC.
отрим этот код:
extension Collection {
func foo() -> Int {
if self.first is Collection {
return (self.first as! Collection).underestimatedCount // ERROR
}
else {
return self.underestimatedCount
}
}
}
Мы получаем страшные и, очевидно, широко озадачивающие:
Протокол 'Collection' может использоваться только в качестве общего ограничения, поскольку он имеет Self или требования к связанному типу.
Тем не менее, это счастливо компилируется:
func foo<C: Collection>(_ c: C) -> Int where C.Iterator.Element: Collection {
if let first = c.first {
return first.underestimatedCount // *
} else {
return c.underestimatedCount
}
}
Зачем?!
В частности, компилятор делаетне знать в*
как связаны типы (тип)first
были реализованы; это только получаетобещание что они были (потому что любой объект типаCollection
имеет реализовать их). Та же самая гарантия есть в первом примере! Так почему компилятор жалуется на одно, а не на другое?
Мой вопрос: на линии*
что знает компилятор что он не в строкеERROR
?