Sometimes, you need to use a variable that should not be modified during the program execution. Such variables are known as constants, or val variables in Kotlin, where they are declared with the val keyword. The difference between a var variable and a val variable is that we cannot modify the value of a val variable once assigned.

Val variables

The following code introduces two val variables: pi, which represents a well-known mathematical constant, and helloMsg, which represents a string text.

val pi = 3.1415
val helloMsg = "Hello"

println(pi)       // 3.1415
println(helloMsg) // Hello

Both variables cannot be modified, but they can be accessed as many times as we need.

The compiler will produce an error if we try modifying the value of a val variable, so an attempt to compile the code below will result in an error: Val cannot be reassigned.

val pi = 3.1415
pi = 3.1416 // error line

If a val variable is used before it is assigned a value, the compiler will also produce an error:

val boolFalse: Boolean
println(boolFalse) // error line

With the code above, you will get the error Variable 'boolFalse' must be initialized. To fix it, assign a value before accessing the variable:

val boolFalse: Boolean // not initialized
boolFalse = false      // initialized
println(boolFalse)     // no errors here

Notice that the value of a val variable can be reassigned to a var variable without any restrictions and the value of a regular variable can be changed as many times as needed:

val count = 10
var cnt = count
cnt = 20 // no errors here, cnt is not a constant

Val variables and mutability

It is important to note that val is not a synonym of immutable. In the following example, we will use a MutableList, which is an ordered set of elements of the same type.

// list creation
val myMutableList = mutableListOf(1, 2, 3, 4, 5)
// trying to update the list
myMutableList = mutableListOf(1, 2, 3, 4, 5, 6) // error line

The second line won’t compile, since we are trying to reassign a val variable. However, there is one essential point to remember.

It is always possible to change the internal state of a val variable: while it is prohibited to reassign the variable, its content can be modified in some other ways.

So, the following code is correct:

// list creation
val myMutableList = mutableListOf(1, 2, 3, 4, 5)
// adding a new element
myMutableList.add(6)   // it works
// printing the list
println(myMutableList) // [1, 2, 3, 4, 5, 6]

As you can see, this code changed the internal state of the list by adding another integer number. When we invoked the add() function, we changed not the variable itself but the list it represents.

If you are familiar with the Java programming language, it may be easier for you to think about Kotlin val variables as Java final variables. They are quite similar: both prohibit reassigning a value to the variable but allow changing the internal state of the object.

Const variables

In Kotlin, there is also a const modifier, which is used before the val keyword to declare a compile-time constant. The value of a const variable is known at compile time and won’t be changed at runtime:

const val MY_STRING = "This is a constant string"

The following code will give you an error, since the value is unknown before the program execution and it is not a constant:

const val MY_STRING = readln() // not a constant String!!!

There are some restrictions on when the const modifier can be applied. First, it can only be used with a String or a primitive type variable:

const val CONST_INT = 127
const val CONST_DOUBLE = 3.14
const val CONST_CHAR = 'c'
const val CONST_STRING = "I am constant"
const val CONST_ARRAY = arrayOf(1, 2, 3) // error: only primitives and strings are allowed

Besides, const variables need to be declared on top level, outside of any functions:

const val MY_INT_1 = 1024 // correct line

fun main() {
    const val MY_INT_2 = 2048 // error: Modifier 'const' is not applicable to 'local variable'
}

When to use val variables

We hope you now understand how the val keyword works for variables. It’s about time to figure out when to use it.

A good practice is to use val variables by default. Then, when it appears to be necessary for the code, change them to var variables:

var a = 1024
val b = 256
val c = 128
a += b * c

This approach allows you to write programs with the minimum number of mutable variables, which leads to fewer errors.

Conclusion

  • In Kotlin, constant variables are declared with the val keyword.
  • You can treat val variables just as regular variables, except for value reassignment.
  • The val keyword forbids changing the variable value, but you can change the internal state of what the variable represents.
  • For compile-time top-level constants, you can use the const modifier.
  • Using val variables whenever you can is a good practice that will allow you to avoid errors.

Leave a Reply