Skip to main content

Kotlin Variables

Variables are one of the most fundamental concepts in programming. They serve as containers for storing data values that can be used and manipulated throughout your program. In this tutorial, we'll explore how variables work in Kotlin and what makes them unique compared to other programming languages.

Introduction to Variables in Kotlin

In Kotlin, variables are particularly flexible and powerful due to the language's modern design. Kotlin variables have two key characteristics that make them stand out:

  1. Type inference - Kotlin can automatically determine variable types
  2. Immutability options - Kotlin lets you choose between mutable and immutable variables

Let's dive into these concepts and see how variables work in practice.

Declaring Variables in Kotlin

Kotlin provides two main keywords for declaring variables:

  • val - for immutable variables (cannot be reassigned)
  • var - for mutable variables (can be reassigned)

Using val for Immutable Variables

When you want to create a variable whose value cannot be changed after initialization, use the val keyword:

kotlin
val name = "John"
val age = 30
val isStudent = false

Once defined, you cannot reassign a value to a val variable:

kotlin
val score = 100
// score = 200 // This would cause a compilation error

Using var for Mutable Variables

When you need a variable that can be changed later in the program, use the var keyword:

kotlin
var counter = 0
counter = 1 // This is perfectly fine
counter = 2 // We can change it as many times as needed

Here's a complete example showing the difference:

kotlin
fun main() {
val constantValue = 100
var changingValue = 100

// constantValue = 200 // Error: Val cannot be reassigned
changingValue = 200 // This works fine

println("Constant value: $constantValue")
println("Changing value: $changingValue")
}

Output:

Constant value: 100
Changing value: 200

Type Inference and Explicit Type Declaration

Kotlin has a powerful type inference system that can automatically determine the type of a variable from the value it's initialized with.

Implicit Type Declaration (Type Inference)

In most cases, you don't need to specify the type explicitly:

kotlin
val name = "Alice"    // Compiler infers that name is a String
val age = 25 // Compiler infers that age is an Int
val pi = 3.14 // Compiler infers that pi is a Double

Explicit Type Declaration

You can also explicitly declare the type if needed:

kotlin
val name: String = "Bob"
val age: Int = 30
val temperature: Double = 98.6

This becomes necessary when initializing a variable later or when you want to be explicit about the type:

kotlin
val message: String  // Type is required when not initializing immediately
// Some code...
message = "Hello" // Initialization happens later

Variable Initialization

In Kotlin, variables need to be initialized before use. This helps prevent null pointer exceptions and makes your code safer.

Immediate Initialization

The most common approach is to initialize variables when declaring them:

kotlin
val userId = 1001
var score = 0

Deferred Initialization

Sometimes you might want to declare a variable first and initialize it later:

kotlin
val response: String
if (isSuccess) {
response = "Operation completed successfully"
} else {
response = "Operation failed"
}
println(response) // The compiler knows response is initialized at this point

For more complex scenarios, Kotlin provides several mechanisms:

lateinit (for var only)

The lateinit modifier allows you to avoid initializing a non-null variable at the point of declaration:

kotlin
lateinit var userInput: String

fun processInput() {
userInput = readLine() ?: ""
println("You entered: $userInput")
}

lazy initialization (for val)

For immutable variables, you can use lazy initialization:

kotlin
val expensiveData: List<String> by lazy {
println("Computing expensive data...")
loadDataFromDatabase() // This runs only when expensiveData is accessed
}

fun main() {
println("Program started")
println("Data size: ${expensiveData.size}") // First access triggers initialization
println("Data first element: ${expensiveData[0]}") // No initialization here
}

Variable Scope

The scope of a variable defines where in the code the variable can be accessed.

Local Variables

Variables declared within a function or block are only accessible within that function or block:

kotlin
fun calculateArea() {
val width = 10
val height = 5
val area = width * height
println("The area is $area")
}

// width, height, and area are not accessible here

Top-Level Variables

Variables declared at the top level of a file are accessible throughout the file:

kotlin
val MAX_COUNT = 100 // A top-level variable

fun incrementCounter(counter: Int): Int {
return if (counter < MAX_COUNT) counter + 1 else counter
}

Constants in Kotlin

For true constants in Kotlin, you can use the const modifier along with val. The const modifier can only be used with primitive types and String:

kotlin
const val MAX_LOGIN_ATTEMPTS = 3
const val API_KEY = "abc123xyz456"

These are compile-time constants and are more efficient than regular immutable variables.

Practical Examples

Let's look at some real-world applications of variables in Kotlin:

User Profile Management

kotlin
fun main() {
// User profile information
val userId: Long = 12345
val username: String = "kotlin_lover"
var email: String = "[email protected]"
var experiencePoints: Int = 100
val accountCreationDate: String = "2023-01-15"
var isPremiumUser: Boolean = false

// Updating mutable information
email = "[email protected]"
experiencePoints += 50
isPremiumUser = true

// Display user profile
println("User Profile:")
println("ID: $userId")
println("Username: $username")
println("Email: $email")
println("XP: $experiencePoints")
println("Member since: $accountCreationDate")
println("Premium user: $isPremiumUser")
}

Output:

User Profile:
ID: 12345
Username: kotlin_lover
Email: [email protected]
XP: 150
Member since: 2023-01-15
Premium user: true

Temperature Converter

kotlin
fun main() {
val temperatureInCelsius = 25.0

// Convert to Fahrenheit: (C × 9/5) + 32
val temperatureInFahrenheit = (temperatureInCelsius * 9/5) + 32

// Convert to Kelvin: C + 273.15
val temperatureInKelvin = temperatureInCelsius + 273.15

println("Temperature conversion results:")
println("$temperatureInCelsius°C = $temperatureInFahrenheit°F")
println("$temperatureInCelsius°C = $temperatureInKelvin K")
}

Output:

Temperature conversion results:
25.0°C = 77.0°F
25.0°C = 298.15 K

Shopping Cart Total Calculator

kotlin
fun main() {
// Product prices
val breadPrice = 2.99
val milkPrice = 1.79
val eggsPrice = 3.49

// Quantities
var breadQuantity = 2
var milkQuantity = 1
var eggsQuantity = 2

// Calculate initial subtotal
var subtotal = (breadPrice * breadQuantity) +
(milkPrice * milkQuantity) +
(eggsPrice * eggsQuantity)

// Apply discount if subtotal is over $10
val discountThreshold = 10.0
val discountRate = 0.1 // 10% discount

var discount = 0.0
if (subtotal >= discountThreshold) {
discount = subtotal * discountRate
}

// Calculate final total
val total = subtotal - discount

// Print receipt
println("SHOPPING CART")
println("-------------")
println("Bread ($breadQuantity) : $${breadPrice * breadQuantity}")
println("Milk ($milkQuantity) : $${milkPrice * milkQuantity}")
println("Eggs ($eggsQuantity) : $${eggsPrice * eggsQuantity}")
println("-------------")
println("Subtotal : $$subtotal")
println("Discount : $$discount")
println("Total : $$total")
}

Output:

SHOPPING CART
-------------
Bread (2) : $5.98
Milk (1) : $1.79
Eggs (2) : $6.98
-------------
Subtotal : $14.75
Discount : $1.475
Total : $13.275

Best Practices for Using Variables in Kotlin

  1. Prefer val over var: Use immutable variables (val) whenever possible. This leads to more predictable code with fewer side effects.

  2. Use meaningful variable names: Choose names that clearly describe the purpose of the variable.

  3. Use type inference: Let Kotlin infer the types unless you have a specific reason to declare them explicitly.

  4. Initialize variables when declaring them: When possible, provide an initial value at the point of declaration.

  5. Use the most specific type needed: Select the appropriate data type for your variables to ensure type safety.

  6. Keep variable scope as limited as possible: Declare variables in the narrowest scope needed to minimize exposure.

Summary

In Kotlin, variables provide a way to store and manipulate data. The key points covered in this tutorial include:

  • Using val for immutable variables and var for mutable ones
  • Leveraging Kotlin's type inference system
  • Declaring variables with explicit types when needed
  • Understanding different initialization patterns
  • Working with variable scope
  • Using constants with the const modifier
  • Applying variables in real-world scenarios

By understanding how variables work in Kotlin, you've taken an important step in your journey to becoming a Kotlin developer. Variables are the building blocks of your programs, and mastering them will help you write cleaner, more efficient code.

Additional Resources and Exercises

Exercises

  1. Create a program that calculates the average of three test scores stored in variables.

  2. Write a program that converts a given number of minutes into hours and minutes.

  3. Create a BMI calculator that takes height (in meters) and weight (in kilograms) as variables and calculates the BMI.

  4. Write a simple banking application that tracks account balance using appropriate variable types.

Further Reading



If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)