172 похожих чатов

Привет! Подскажите плиз, получаю такую ошибку: Cannot convert value of type

'CellViewModel<ListItemTableViewCell>' to type 'CellViewModel<UITableViewCell>' in coercion

ListItemTableViewCell под капотом наследуется от UITableViewCell, почему не получается сконвертить одно в другое?

4 ответов

9 просмотров

Очень интересный вопрос. Всё просто, в Swift пошли по пути наименьшего сопротивления, а это в свою очередь означает, что "все" дженерики находятся в инвариантной позиции. Несмотря на это, всё ж стандартные коллекции, скажем обычный массив, который имеет дженерик параметр Element, находится в ковариантой позиции. Именно поэтому 1ый пример нерабочий, а 2ой рабочий.

Руслан Лутфуллин
screenshot Очень интересный вопрос. Всё просто, в Swift пошли...

Вообще говоря возможность такой замены зависит от использования этого самого дженерик параметра. Если дженерик параметр используется только в качестве возвращаемого значения для методов и ридонли сабскриптов и свойств, то он находтся в ковариантной позиции и такая замена возможна: class B: A { } let foo0 = Foo<B> let foo1 = Foo<A> = foo0 Если дженерик параметр используется в качестве параметров у методов, то он находится в инвариантной позиции и замена выше уже невозможно, а такая замена возможна:: class B: A { } let foo0 = Foo<A> let foo1 = Foo<B> = foo0 Если дженерик параметр используется в обоих случаях, то единственный рабочий вариант в таком случае, когда A и B один и тот же тип. Это вообще говоря довольно сложная тема, поэтому в Swift все дженерик просто по умолчанию находятся в инвариантной позиции.

Руслан Лутфуллин
screenshot Очень интересный вопрос. Всё просто, в Swift пошли...

ну вроде логично, ведь это разные типы. то что там в конкретике используется nsview и nsbutton видимо не имеет значения, там ведь мог бы быть какой-нибудь double. если вариант ниже с массивами компилируется, то возможно это какими-нибудь расширениями и кастомными инициализаторами в массиве сделано

Denis Kim
ну вроде логично, ведь это разные типы. то что там...

Это связано исключительно с понятиями ковариантности/контрвариантности Стандартные value типы на уровне компилятора поддерживают возможную ковариантность/контравариантность, тогда как пользовательские типы такой возможности не имеют, потому что за этим довольно сложно статически проследить, что бы это ничего не нарушило. То есть да, компилятору сложно проверить все места где используется этот параметр, что бы убедиться, что тут именно NSView —> NSButton, а не NSView —> Double. Но при этом, это работает в более простых случаях, не связанных с дженериками, скажем: let a = (NSView) -> NSButton = { ... } let b = (NSButton) -> NSView = a

Похожие вопросы

Обсуждают сегодня

Господа, а что сейчас вообще с рынком труда на делфи происходит? Какова ситуация?
Rꙮman Yankꙮvsky
29
А вообще, что может смущать в самой Julia - бы сказал, что нет единого стандартного подхода по многим моментам, поэтому многое выглядит как "хаки" и произвол. Короче говоря, с...
Viktor G.
2
30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Ребят в СИ можно реализовать ООП?
Николай
33
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Карта сайта