Я только что наткнулся на этого любопытного повара ie и не могу понять, удивляюсь ли я тому, что это работает не так, как ожидалось, или что я впервые вижу это в прошлом пять лет, используя Swift каждый день.
Теперь я ожидал, что тип Bar
будет доступен с Baz
, но это не так:
class Foo<Bar> {
func bar() -> Bar? { nil }
}
class Baz: Foo<String> {
override func bar() -> Bar? { nil } // ? Use of undeclared type 'Bar'…
}
Это легко решается с помощью typealias
:
class Foo<Bar> {
typealias Bar = Bar // This just feels so wrong…
func bar() -> Bar? { nil }
}
class Baz: Foo<String> {
override func bar() -> Bar? { nil } // ? That's it…
}
Мои вопросы: это упоминается или объясняется где-нибудь в официальных документах? Какая польза от сокрытия Bar
от наследования классов?
Одна из причин того, что это редкий случай, возможно, заключается в том, что мы часто передаем тип c generic:
class Foo<Bar> {
func bar() -> Bar? { nil }
}
class Baz<Bar>: Foo<Bar> {
override func bar() -> Bar? { nil } // ? No problems…
}
И используйте протоколы с associatedtype
, который выполняет ту же работу, что и typealias
выше:
protocol P {
associatedtype Bar
}
class Foo<Bar>: P {
func bar() -> Bar? { nil }
}
class Baz: Foo<String> {
override func bar() -> Bar? { nil } // ? All good…
}
PS Я не спрашиваю, как это исправить. Я хочу знать, если текущее поведение упоминается где-либо в официальной документации или, в противном случае, если есть заслуживающая доверия статья, объясняющая причины, почему это работает так, как работает.