Site icon Treehouse Blog

An Absolute Beginner’s Guide to Kotlin

kotlin

What’s Kotlin?

Kotlin is a modern programming language maintained as an open source project by JetBrains, a world leader in IDEs. Back in 2011, JetBrains was writing primarily Java code and looking for a new programming language to help make them more efficient programmers. Ultimately, they decided to create a new programming language called Kotlin.

Over the years Kotlin has grown to become a drop-in replacement for Java, allowing Java developers to easily upgrade to a more expressive language. Not only that, in May of 2017 Google announced Kotlin would be an officially supported language on the Android platform. With JetBrains and now Google supporting the project, it’s no surprise that Kotlin has seen such a large rise in popularity.

Using Kotlin

To get started with Kotlin, the first thing you’ll need is somewhere to write code. The easiest place to try writing Kotlin code is the try.kotlinlang.org website. It offers lots of Kotlin practice, and if you sign-in (it has most major social networks as sign-in options), you can even create your own programs that it will save for you in the cloud (once signed-in click the folder button with a plus sign on it to create a new program).

You can also practice using Kotlin in an IDE like IntelliJ IDEA. To create a Kotlin project in IntelliJ IDEA follow these steps.

If you’d like to use Kotlin in an Android project, check out this page for instructions.

Kotlin Basics

Variables

To create a variable in Kotlin we use the var keyword.

var greeting: String = "Hello World!"

This code tells the computer to create a new variable named ‘greeting’ which will be of type String and contain the text, “Hello World!”.

Also, you can usually omit the type argument. If Kotlin can figure out what type something is, you don’t need to explicitly specify it. A more common way of writing the above example would be:

var greeting = "Hello World!" // The type is inferred to be a String

Once you’ve created a variable you can easily modify it by setting it equal to something else:

var greeting = "Hello World!"
greeting = "Hello Kotlin!"

Though sometimes when you create a variable, you’d rather it not be able to change. In Kotlin there are two types of variables: mutable and immutable. Mutable means that the variable CAN be changed, and immutable means that it CANNOT be changed. To create a mutable variable we use the var keyword like we’ve been doing. However, to create an immutable variable we need to use the val keyword.

If we change our greeting example to use val instead of var, then the second line will give us a compiler error because we’re no longer allowed to modify our greeting variable:

val greeting = "Hello World!"
greeting = "Hello Kotlin!" // Compiler error: val cannot be reassigned

Strings

In our example above we’ve been making use of the String type. Let’s see how we can combine two Strings together by using the + operator.

val language = "Kotlin"
val creator = "JetBrains"
val description = language + " is created by " + creator
// description = "Kotlin is created by JetBrains"

Combining Strings together like this is known as concatenation. Sometimes using the + operator to concatenate can be a bit cumbersome. When that’s the case, it’s usually better to use something known as String Templates. String Templates let us use variables inside double quotes by prefacing the variable with a $:

val releaseDate = "July 2011"
val releaseString = "Kotlin was released in $releaseDate"
// releaseString = "Kotlin was released in July 2011"

The resulting releaseString contains the value of releaseDate along with the rest of the String. We could’ve accomplished the same thing with the + operator, but this way is much cleaner and easier to read.

For these examples we’ve been using the val keyword which means that we can’t change the String after creating it. Remember, if you want to be able to modify a variable after creating it, just use the var keyword.

Numbers

Along with Strings Kotlin also offers several numeric types. The most important of these are Int, Long, Float, and Double. Int and Long are used for whole numbers, whereas Float and Double are used for decimal values. Also, Int and Float each use 32 bits to store their values, whereas Long and Double use 64. So if you need to store a really big number you’d use a Long or Double instead of an Int or Float.

By default, any integer values will be typed as Int and any decimal values will be typed as Double:

val num1 = 42 // Int
val num2 = 3.14 // Double

If you’d like to declare a number as a Float or Long, you need to add an ‘f’ or ‘L’ to the end of the number:

val num1 = 42L // Long
val num2 = 3.14f // Float

You can also convert between different numeric types by using the toType functions:

val num1 = 42.toFloat() // Float
val num2 = num1.toDouble() // Double

Also, when using Kotlin you can use underscores to make numbers more readable:

val distToMoon = 92_960_000 // miles (inferred type Int)

Booleans

Kotlin also contains a Boolean type. Boolean types are used to represent either a true or false value. To set a Boolean variable use the true or false keywords:

val isGoodDay = true
val isBadDay = false

Nullability

In most languages, when you create a variable but don’t set it equal to something, it gets a value of NULL, which can be thought of as not being equal to anything. NULL values cause issues in many programs when the program tries to do something with a NULL value. For example:

// java code
String address;
println(address);

The above code creates a String variable named ‘address’ and then tries to print out the address before it has been set. This results in a NullPointerException and crashes the program.

In Kotlin we handle NULL a bit differently. Instead of variables being defaulted to NULL, it’s actually an error to not initialize a variable:

val x: Int // Error - variable must be initialized

Also, you can’t just set a variable equal to NULL. You’d need to first mark that variable’s type as nullable by using questionmark:

val x: Int = null // Error - null cannot be a value for non-null type Int
val x: Int? = null // OK
val y: String = null // Error - null cannot be a value for non-null type String
val y: String? = null // OK

There’s also a couple of operators to help us deal with NULL values. Let’s look at the following example:

val name: String? = null
println(name.length) // Error - Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?

We declare a nullable String variable called ‘name’, and set it equal to null. Then we try to print the length of our String. However, since Kotlin knows that name might be NULL it shows us an error. To fix this error we have two options, we can either assert (!!) that name isn’t NULL, or we can use what’s known as a safe call (?).

Using a safe call (e.g. name?.length) means that if name is NULL, instead of trying to get the length of a NULL object and causing an error, it will just return NULL:

val name: String? = null
println(name?.length) // prints “null”

You would use a non-null assertion (!!) when you know for sure that a nullable variable cannot be null, as shown here:

var name: String? = null
name = "Treehouse"
println(name!!.length) // prints "9"

Collections

A collection contains multiple items that can be accessed through subscripting. Kotlin offers three main types of collections: Arrays, Lists, and Maps.

Arrays

An array is an indexed collection of items that all have the same type. To create an array, we use the arrayOf function:

val cardNames: Array = arrayOf("Jack", "Queen", "King")

And just like earlier, as long as Kotlin can figure out what type our variable is, we don’t need to specify a type:

val cardNames = arrayOf("Jack", "Queen", "King")

To access an item from the array we use the index (starting at 0) of the item we’d like to access. So to access the first item in the array we would use:

val firstCard = cardNames[0] // firstCard = "Jack"

To replace an existing item in the array, just subscript that item and set it equal to a different value:

cardNames[0] = "Ace"

Arrays are fixed-size; once created, there’s no way to add or remove items from an array. If you’d like to add and remove items from a collection, try using a List.

Are you ready to start learning?

Learning with Treehouse for only 30 minutes a day can teach you the skills needed to land the job that you’ve been dreaming about.

Start a Free Trial

Lists

In Kotlin there are two types of List: List and MutableList. The List class functions pretty similarly to an Array, except that you can’t modify the items in a List. However, the MutableList class lets us modify the items in the list as well as add and remove items. To create a new MutableList we use the mutableListOf function:

val cards = mutableListOf("Jack", "Queen", "King")

Using a MutableList gives us several options for adding/removing items:

cards.add("Ace") // Jack, Queen, King, Ace
cards.remove("Jack") // Queen, King, Ace
cards.clear() // empty list
cards.addAll("Jack", "Queen", "King", "Ace") // Jack, Queen, King, Ace

Maps

The last important collection type is a Map (and MutableMap). Maps let us store key-value pairs and access the values by providing the keys.

For example, if we wanted to store numeric information along with our card data we could create a map like this:

val cards = mapOf("Jack" to 11, "Queen" to 12, "King" to 13)

Above we have specified the card names as the keys and have mapped them to their corresponding values. Here we’re using String keys and Int values, but we’re not restricted to just Strings and Ints; you can use any types in a Map.

To access a specific card, just use the key to retrieve the value:

val jackValue = cards["Jack"] // 11

If we’d like to add items to our cards Map, we’ll first need to change it to a MutableMap, and then we can just set the new values:

val cards = mutableMapOf("Jack" to 11, "Queen" to 12, "King" to 13)
cards["Ace"] = 1

You can also use the toMutableMap function to turn a Map into a MutableMap:

val cards = mapOf("Jack" to 11, "Queen" to 12, "King" to 13)
val mutableCards = cards.toMutableMap()
mutableCards["Ace"] = 1

Control Flow

Looping

In Kotlin there are two types of loops: for loops and while loops. You can use a for loop to iterate through a collection like this:

val cards = mutableListOf("Jack", "Queen", "King")
for (card in cards) {
    println(card)
}

The println function will print out the value of whatever is between the parentheses. So this code prints each card on a new line:

Jack
Queen
King

A for loop can also be used to loop over a range of numbers. To print the numbers 1 through 10 you could use the following for loop.

for (i in 1..10) {
   println(i)
}

However, if you wanted to loop down from 10 to 1, instead of two dots you would need the downTo operator:

for (i in 10 downTo 1) {
   println(i)
}

You can also use a for loop to loop through a Map. This code loops through the cards Map and prints out the name and value of each card:

val cards = mapOf("Jack" to 11, "Queen" to 12, "King" to 13)
for ((name, value) in cards) {
    println("$name, $value")
}

In addition to for loops, Kotlin also offers a while loop. While loops are used to loop until a certain condition is met:

while (stillDownloading) {
   println("Downloading…")
}

This code will print “Downloading…” until the stillDownloading variable is false.

If Expression

Most languages have an if statement, but in Kotlin we have an if expression (it returns a value). So in addition to using if statements the normal way:

val a = 5
val b = 3
var aIsBigger = false
if (a > b) {
   aIsBigger = true
} else {
   aIsBigger = false
}

We can also use them to set our variables (which lets us use a val instead of a var!):

val aIsBigger = if (a > b) {
    true
} else {
    false
}

Not only that, if there’s only one line between the brackets, then the brackets are optional:

val aIsBigger = if (a > b) true else false

When Expression

Instead of a switch statement, in Kotlin we get a when expression. You can use a when expression to compare a value to multiple values and do something different based on which value it equals. Here’s an example that takes in the integer value of a card and prints out the card’s name:

when (cardInt) {
    11 -> println("Jack")
    12 -> println("Queen")
    13 -> println("King")
}

Just like an if expression, a when expression can be used to return value. So we could set up a cardName variable like this:

val cardName = when (cardInt) {
    11 -> "Jack"
    12 -> "Queen"
    13 -> "King"
    else -> "Other"
}

Notice that we needed to include an else branch. If you’re using a when to return a value, then it needs to be exhaustive. Since there are lots of integers our when expression doesn’t account for (e.g. -107865), we need to include the else branch to make sure that cardName gets set to something.

Functions

Functions are blocks of code that you can use to simplify your programs. For example, println is a function that takes in a variable and prints its value to the screen.

In Kotlin we can create our own functions by using the ‘fun’ keyword and then providing a name for the function:

fun printJack() {
   println("Jack")
}

We can also add parameters to our function:

fun printCard(cardName: String, cardValue: Int) {
   println("$cardName = $cardValue")
}

If we’d like, instead of printing out the card, we could return it as a String object:

fun getCardString(cardName: String, cardValue: Int): String {
   return("$cardName = $cardValue")
}

Another cool thing about Kotlin is that when you find yourself writing a function with only a return statement, you can omit the brackets and return keyword and instead opt for an equals sign:

fun getCardString(cardName: String, cardValue: Int): String = "$cardName = $cardValue"

Kotlin can even infer that the return type will be a String. There’s nothing wrong with declaring your return types, but in Kotlin it’s not always necessary:

fun getCardString(cardName: String, cardValue: Int) = "$cardName = $cardValue"

Conclusion

If you’ve made it this far, then congratulations! You’ve now got a good base to start building some serious Kotlin knowledge. It’s a lot to take in, but we’ve really only scratched the surface of Kotlin. There’s so much more to learn, and here at Treehouse we’re working on courses to provide you with all the Kotlin learning that you need. Stay tuned for more!

If you want to learn the basics of Kotlin, take our Kotlin for Java Developers course. It’s a great course that builds a headless solitaire app, and don’t worry if you’re not already a Java developer. After what you’ve learned in this post, you’ll have no trouble following along!

Exit mobile version