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

Что-То я думал, что понимаю, как работает реификация, но как-то

не могу объяснить такое поведение, как ниже.
Может кто-то поможет?
import kotlin.reflect.KType

fun main() {
println(object : KTypeToken<List<*>>() {}.type)
println(typeOf<List<*>>())
}

abstract class KTypeToken<T> {
val type: KType = this::class.supertypes.first { it.classifier == KTypeToken::class }.arguments[0].type!!
}

inline fun <reified T> typeOf(): KType = object : KTypeToken<T>() {}.type

Выводит
kotlin.collections.List<*>
[ERROR : Unknown type parameter 0. Please try recompiling module containing "[container not found]"]

42 ответов

30 просмотров

А причём тут реификация? То, что ошибка странно, но там ведь даже она не используется вроде

Andrey-Antipov Автор вопроса
Ilya
А причём тут реификация? То, что ошибка странно, н...

Нет, она используется в функции typeOf для параметра T

Andrey-Antipov Автор вопроса
Ilya
Так оно и без reified скомпилится

Да, компилится, но что-то не работает :(

Andrey Antipov
Да, компилится, но что-то не работает :(

Та же ошибка? А без inline тоже не работает?

Andrey-Antipov Автор вопроса
Ilya
Та же ошибка? А без inline тоже не работает?

Без inline и не будет 100%. Там же трюк с анонимным наследником KTypeToken, чтобы сохранить в рантайме информацию о типе, подставленном вместо T, который стирается. А если без inline и reified, то эта информация и не доедет до момента создания наследника, создастся как наследник сырого типа. Не понятно, почему с inline и reified не доезжает.

Vladimir Petraković
Так-то не должно 🤔

Почему? Насколько я знаю оно не скомпилится ток если T::class используется

Andrey-Antipov Автор вопроса

я не знаю почему вы так долго это обсуждаете, reified сохраняет класс и не стирает его, но вы в typeOf его используете как дженерик класса, который в любом случае е может быть reified, так что то, что вы делаете в инлайн функции - бессмысленно.

Ilya
Почему? Насколько я знаю оно не скомпилится ток ес...

Так здесь точно так же нужен конкретный тип

Vladimir Petraković
Так здесь точно так же нужен конкретный тип

Мы же просто дженерик в класс передаём, это делали в джаве и без reified

Vladimir Petraković
Ну вообще да, он может и стереться

Ну он и сотрётся, я об этом с самого начала и говорю)

Может, это из-за wildcard?

Vladimir Petraković
В такой функции не должен

В функции нет, а в классе да

Andrey-Antipov Автор вопроса
Vladimir Petraković
Может, это из-за wildcard?

Нет: fun main() { println(object : KTypeToken<List<String>>() {}.type) println(kTypeOf<List<String>>()) } kotlin.collections.List<kotlin.String> [ERROR : Unknown type parameter 0. Please try recompiling module containing "[container not found]"]

Andrey-Antipov Автор вопроса
Ilya
И всё-таки попробуйте без inline

Пробовал уже. Тот же результат

Ilya
И всё-таки попробуйте без inline

Без inline вызов этой функции не будет приводить к созданию нового анонимного класса, в котором сохранится информация о типе

Vladimir Petraković
Без inline вызов этой функции не будет приводить к...

Так если оно и без inline и с inline не работает, то в данном случае это не важно, я просто локализирую проблему

Andrey Antipov
Без inline и не будет 100%. Там же трюк с анонимны...

предполагаю что нужно иссью, не подумали, что так будут использовать

Aλex Sokol
предполагаю что нужно иссью, не подумали, что так ...

Там проблема только с самой функцией, а не с inline или reified

Ilya
Там проблема только с самой функцией, а не с inlin...

нет, проблема с тем, что reified типы не доезжают до анонимных наследников

Andrey Antipov
Без inline и не будет 100%. Там же трюк с анонимны...

Этот трюк не работает. Сохраняйте T::class.

Andrey-Antipov Автор вопроса
Ilmir
Этот трюк не работает. Сохраняйте T::class.

И как мне T::class поможет сохранить в рантайме полную информацию о типе List<String>?

Ilmir
Этот трюк не работает. Сохраняйте T::class.

А как оно тогда там работает? https://t.me/kotlin_lang/223602

Ilmir
Этот трюк не работает. Сохраняйте T::class.

и что даже иссью не надо писать, не сделать это никак?

Andrey-Antipov Автор вопроса
Ilmir
Этот трюк не работает. Сохраняйте T::class.

И да, сам трюк с анонимным классом, прекрасно работает. А вот inline reified функция на его основе - нет

Vladimir Petraković
А как оно тогда там работает? https://t.me/kotlin_...

Через сохранение типа и передачи его же в родителя. Очень хитро сделано: https://github.com/FasterXML/jackson-core/blob/9e33b3a5b53c7bce13ae2a00dcf097fcab919969/src/main/java/com/fasterxml/jackson/core/type/TypeReference.java

Andrey-Antipov Автор вопроса
Ilmir
Через сохранение типа и передачи его же в родителя...

Ну внутри там всё хитро, конечно. Но как это связано с тем, что в одном случае компилятор создаёт классы с конкретным типом для каждого вызова инлайн-функции, а в другом - нет?

Aλex Sokol
и что даже иссью не надо писать, не сделать это ни...

Ишью надо делать. По идее, это баг в kotlin.reflect, так как в джавовом рефлекшне всё работает.

Andrey-Antipov Автор вопроса
Andrey Antipov
Это не в рефлекшене проблема

Ну ХЗ. До ввода typeOf, официальный workaround использовал джавовый рефлекшн: https://gist.github.com/udalov/bb6f398c2e643ee69586356fdd67e9b1. А то, что reified T не передаётся в класс - это логично, если учесть, что инлайнер работает на байткоде, а там уже java.lang.Object вместо T.

Vladimir Petraković
Ну внутри там всё хитро, конечно. Но как это связа...

В одном он вкомпиливает нужный тип сразу, а в другом - через байткод, к котором T уже стирается.

Andrey-Antipov Автор вопроса
Ilmir
Ну ХЗ. До ввода typeOf, официальный workaround исп...

Да, похоже бага в kotlin.reflection. Если написать аналогичный код для java.reflection, то reified inline работает

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

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

а зачем этот вопрос для удаления из чата?
Mёdkinson Medvezhkin
63
Добрый день. Хочу сделать отрисовку по команде на панели. Почему-то рисуется только при втором вызове. С чем может быть связано, не подскажете? procedure TForm1.FormDblClick(...
Kirill Filippenok
20
Всем доброго дня! Подскажите может кто использовал связку Pagebuilder + Clientsetting. Сами параметры с типом pagebuilder в модуле Clientsetting работают нормально, можно такж...
Александр Добриков
12
А почему в си некоторые вещи работают с двойными кавычками некоторые с одинарными? Нельзя было все сделать с одними или чтоб работало с разными? например чтоб выводить строки ...
.
15
Всем привет! Нужен совет от опытных. Переношу свой проект с Делфи 10.2 Токио на Лазарус 3.2 установленный через инсталлятор fpcupdeluxe-x86_64-win64. При импортировании проект...
Дмитрий Завгородний
7
Всем привет! Подскажите. Я написал приложение на Delphi 10.2 Tokyo под Windows 10. И передо мной стал вопрос о том чтобы сделать это приложение кроссплатформенным (под Linux и...
Дмитрий Завгородний
24
Good afternoon, I just started learning php in conjunction with mysql. I am registering a system on a local Mamp server using phpMyAdmin. It seems to be stored normally in the...
ManGo
1
Эх кто-то пришел и весь праздник испортил :( You need complex FBX scene importing setup to change things on import? good luck with that. You need navigation and pathfinding? g...
Serg Gini
5
Добрый день! Такая проблема возникла, написал код на Python, который компилирует, собирает и запускает файлы .s А в случае работы нужно то же самое делать для .asm Чем эти фа...
A Mori
5
Всем привет! procedure TForm1.FormCreate(Sender: TObject); type TStartEnd = record S: Byte; E: Byte; end; var a, b: TStartEnd; begin {1} a.S := 1; {2} a.E := 2; ...
Руслан Михайлович
10
Карта сайта