Компиляция командной строки REPL очень похожа на компиляцию скрипта .kts, , результат которой документирован здесь . Каждая строка компилируется как отдельный скрипт.
kotlinc
создает новый класс для каждой введенной вами строки и создает блок init
, который выполняет вашу строку. Если вы объявите свойство / функцию / класс, это будет опубликованное свойство / функция / подкласс c сгенерированного класса.
Конструктор сгенерированного класса принимает экземпляры ВСЕХ классов, которые были сгенерированы до него (класс для каждая строка) и использует их в качестве получателей для вашего кода.
Это можно проверить, если вы используете отражение в компиляторе командной строки. Вот несколько примеров, которые подтверждают сказанное мной:
> println(this::class)
class Line_0
> val a = 0
> println(::a.visibility)
PUBLIC
> import kotlin.reflect.full.*
> println(Line_1::class.memberProperties)
[val Line_1.a: kotlin.Int]
> println(Line_1::class.constructors)
[fun <init>(): Line_1]
Вы можете легко создать экземпляр Line_0
:
> println(Line_0::class.java.constructors.first().newInstance())
Line_0@5b8caf1b
Но создание экземпляров других строк требует передачи экземпляров всех предыдущие строки:
> val line0 = Line_0::class.java.constructors.first().newInstance()
> println(Line_1::class.java.constructors.first().newInstance(line0))
Line_1@1baba519
Также вы можете создать бесконечную рекурсию с созданием экземпляров (если вы напишите следующую строку в качестве первой строки в kotlinc
):
Line_0::class.java.constructors.first().newInstance()