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 ответов

77 просмотров

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

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 работает

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

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

Господа, а что сейчас вообще с рынком труда на делфи происходит? Какова ситуация?
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
Карта сайта