Scope
Visibility keywords control who can see what.
Scope controls where things exist. This has an indirect impact on visibility: if something does not exist, it cannot be accessed by anything.
However, scope more directly controls things like garbage collection, as scope helps to determine the lifetime of objects.
Global
Top-level definitions in a Kotlin source file are global in scope. Immutable globals — classes, val
, etc. — will exist for the life of the process that is executing the Kotlin code. Mutable globals — such as var
— have references that will live forever, but the objects that those references reference might come and go as the value of that reference changes.
So, in this code, both the Foo
class and the foo
variable are global and immutable:
class Foo {
fun something() {
println("Hello, world!")
}
}
val foo = Foo()
foo.something()
var bar = Foo()
bar.something()
bar = Foo()
bar.something()
bar
too is considered to be global. The difference is that bar
is mutable. So while anything that bar
points to cannot be garbage collected, once bar
is pointing to something else (e.g., another instance of Foo
), whatever bar
used to point to can be garbage collected.
Instance
Properties defined inside of a class have “instance” scope. Each instance of the enclosing class will have its own set of instance properties, independent of any other instance of that same class.
class Foo(val count: Int)
fun main() {
val instanceOne = Foo(1)
val instanceTwo = Foo(2)
println(instanceOne.count)
println(instanceTwo.count)
}
Here, each instance of Foo
has its own count
property with its own independent value.
Local
Any val
or var
within something smaller than a class is some form of local variable.
Local to Functions
A val
or var
directly inside of a function body is local to that function:
class Foo {
fun something(message: String) {
val length = message.length
println("'$message' has $length characters")
}
}
fun main() {
Foo().something("this is a test")
}
Here, length
is considered to be local to the something()
function. You would be unable to access length
from other functions on Foo
, let alone from outside of Foo
.
Local to Blocks/Lambdas
A variable defined within a block or lambda (i.e., chunk of code in {}
) will be local to that block or lambda:
class Foo {
fun something(messages: List<String>) {
messages.forEach { message ->
val length = message.length
println("'$message' has $length characters")
}
}
}
fun main() {
Foo().something(listOf("this", "is", "a", "test"))
}
Now length
is not local to something()
, but instead is local to the lambda expression supplied to forEach()
. You cannot access length
from elsewhere within something()
, let alone from other methods on Foo
or from outside of Foo
.
Prev Table of Contents Next
This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.