For example, I enter the kotlin console via kotlinc
command.
Then define a variable: val pi = 3.14
, what is its scope ?
I have tried const val PI = 3.14
, which would be an error as following:
error: const 'val' are only allowed on top level or in objects
So, I am wondering what is the scope of code entered in the console ?
Command line REPL compilation is very similar to .kts script compilation, which result is documented here. Each line is compiled as a separate script.
kotlinc
creates a new class for each line you entered and creates an init
block that executes your line. If you declare a property/function/class, it will be a public property/function/subclass of generated class.
Generated class constructor takes instances of ALL classes that were generated before it (a class for each line) and uses them as receivers for your code.
It can be verified if you use reflection in your command line compiler. There are some examples that verify what I said:
> 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]
You can create an instance of Line_0
easily:
> println(Line_0::class.java.constructors.first().newInstance())
Line_0@5b8caf1b
But creating instances of other lines requires passing instances of all previous lines:
> val line0 = Line_0::class.java.constructors.first().newInstance()
> println(Line_1::class.java.constructors.first().newInstance(line0))
Line_1@1baba519
Also, you can create an infinite recursion with creating instances (if you write the following line as the first line in kotlinc
):
Line_0::class.java.constructors.first().newInstance()