[Kotlin] Basic syntax

Kotlin Basic syntax

Kotlin is a cross-platform, statically typed, general-purpose programming language with type inference. Kotlin is designed to interoperate fully with Java, and the JVM version of Kotlin’s standard library depends on the Java Class Library, but type inference allows its syntax to be more concise.

Package definition and imports

Package specification should be at the top of the source file.

1
2
3
4
5
package my.demo

import kotlin.text.*

// ...

It is not required to match directories and packages: source files can be placed arbitrarily in the file system.

See Packages - https://kotlinlang.org/docs/packages.html.

Program entry point

An entry point of a Kotlin application is the main function.

1
2
3
fun main() {
println("Hello world!")
}

Another form of main accepts a variable number of String arguments.

1
2
3
fun main(args: Array<String>) {
println(args.contentToString())
}

print prints its argument to the standard output.

1
2
print("Hello ")
print("world!")

println prints its arguments and adds a line break, so that the next thing you print appears on the next line.

1
2
println("Hello world!")
println(42)

Functions

A function with two Int parameters and Int return type.

1
2
3
fun sum(a: Int, b: Int): Int {
return a + b
}

A function body can be an expression. Its return type is inferred.

1
fun sum(a: Int, b: Int) = a + b

A function that returns no meaningful value.

1
2
3
fun printSum(a: Int, b: Int): Unit {
println("sum of $a and $b is ${a + b}")
}

Unit return type can be omitted.

1
2
3
fun printSum(a: Int, b: Int) {
println("sum of $a and $b is ${a + b}")
}

See Functions - https://kotlinlang.org/docs/functions.html.

Variables

Read-only local variables are defined using the keyword val. They can be assigned a value only once.

1
2
3
4
val a: Int = 1  // immediate assignment
val b = 2 // `Int` type is inferred
val c: Int // Type required when no initializer is provided
c = 3 // deferred assignment

Variables that can be reassigned use the var keyword.

1
2
var x = 5 // `Int` type is inferred
x += 1

You can declare variables at the top level.

1
2
3
4
5
6
val PI = 3.14
var x = 0

fun incrementX() {
x += 1
}

See also Properties - https://kotlinlang.org/docs/properties.html.

Creating classes and instances

To define a class, use the class keyword.

1
class Shape

Properties of a class can be listed in its declaration or body.

1
2
3
class Rectangle(var height: Double, var length: Double) {
var perimeter = (height + length) * 2
}

The default constructor with parameters listed in the class declaration is available automatically.

1
2
val rectangle = Rectangle(5.0, 2.0)
println("The perimeter is ${rectangle.perimeter}")

Inheritance between classes is declared by a colon (: ). Classes are final by default; to make a class inheritable, mark it as open.

1
2
3
4
5
open class Shape

class Rectangle(var height: Double, var length: Double): Shape {
var perimeter = (height + length) * 2
}

See classes and objects and instances.

Comments

Just like most modern languages, Kotlin supports single-line (or end-of-line) and multi-line (block) comments.

1
2
3
4
// This is an end-of-line comment

/* This is a block comment
on multiple lines. */

Block comments in Kotlin can be nested.

1
2
3
/* The comment starts here
/* contains a nested comment */
and ends here. */

See Documenting Kotlin Code for information on the documentation comment syntax.

String templates

1
2
3
4
5
6
7
var a = 1
// simple name in template:
val s1 = "a is $a"

a = 2
// arbitrary expression in template:
val s2 = "${s1.replace("is", "was")}, but now is $a"

See String templates - https://kotlinlang.org/docs/basic-types.html#string-templates for details.

Conditional expressions

1
2
3
4
5
6
7
fun maxOf(a: Int, b: Int): Int {
if (a > b) {
return a
} else {
return b
}
}

In Kotlin, if can also be used as an expression.

1
fun maxOf(a: Int, b: Int) = if (a > b) a else b

See if -expressions - https://kotlinlang.org/docs/control-flow.html#if-expression.

for loop

1
2
3
4
val items = listOf("apple", "banana", "kiwifruit")
for (item in items) {
println(item)
}

or

1
2
3
4
val items = listOf("apple", "banana", "kiwifruit")
for (index in items.indices) {
println("item at $index is ${items[index]}")
}

See for loop - https://kotlinlang.org/docs/control-flow.html#for-loops.

while loop

1
2
3
4
5
6
val items = listOf("apple", "banana", "kiwifruit")
var index = 0
while (index < items.size) {
println("item at $index is ${items[index]}")
index++
}

See while loop - https://kotlinlang.org/docs/control-flow.html#while-loops.

when expression

1
2
3
4
5
6
7
8
fun describe(obj: Any): String =
when (obj) {
1 -> "One"
"Hello" -> "Greeting"
is Long -> "Long"
!is String -> "Not a string"
else -> "Unknown"
}

See when expression - https://kotlinlang.org/docs/control-flow.html#when-expression.

Ranges

Check if a number is within a range using in operator.

1
2
3
4
5
val x = 10
val y = 9
if (x in 1..y+1) {
println("fits in range")
}

Check if a number is out of range using !in operator.

1
2
3
4
5
6
7
8
val list = listOf("a", "b", "c")

if (-1 !in 0..list.lastIndex) {
println("-1 is out of range")
}
if (list.size !in list.indices) {
println("list size is out of valid list indices range, too")
}

Iterate over a range.

1
2
3
for (x in 1..5) {
print(x)
}

Or over a progression.

1
2
3
4
5
6
7
for (x in 1..10 step 2) {
print(x)
}
println()
for (x in 9 downTo 0 step 3) {
print(x)
}

See Ranges and progressions - https://kotlinlang.org/docs/ranges.html.

Collections

Iterate over a collection.

1
2
3
for (item in items) {
println(item)
}

Check if a collection contains an object using in operator.

1
2
3
4
when {
"orange" in items -> println("juicy")
"apple" in items -> println("apple is fine too")
}

Using lambda expressions to filter and map collections:

1
2
3
4
5
6
val fruits = listOf("banana", "avocado", "apple", "kiwifruit")
fruits
.filter { it.startsWith("a") }
.sortedBy { it }
.map { it.toUpperCase() }
.forEach { println(it) }

See Collections overview - https://kotlinlang.org/docs/collections-overview.html.

Nullable values and null checks

A reference must be explicitly marked as nullable when null value is possible. Nullable type names have ? at the end.

Return null if str does not hold an integer:

1
2
3
fun parseInt(str: String): Int? {
// ...
}

Use a function returning nullable value:

1
2
3
4
5
6
7
8
9
10
11
12
13
fun printProduct(arg1: String, arg2: String) {
val x = parseInt(arg1)
val y = parseInt(arg2)

// Using `x * y` yields error because they may hold nulls.
if (x != null && y != null) {
// x and y are automatically cast to non-nullable after null check
println(x * y)
}
else {
println("'$arg1' or '$arg2' is not a number")
}
}

or

1
2
3
4
5
6
7
8
9
10
11
12
// ...
if (x == null) {
println("Wrong number format in arg1: '$arg1'")
return
}
if (y == null) {
println("Wrong number format in arg2: '$arg2'")
return
}

// x and y are automatically cast to non-nullable after null check
println(x * y)

See Null-safety - https://kotlinlang.org/docs/null-safety.html.

Type checks and automatic casts

The is operator checks if an expression is an instance of a type. If an immutable local variable or property is checked for a specific type, there’s no need to cast it explicitly:

1
2
3
4
5
6
7
8
9
fun getStringLength(obj: Any): Int? {
if (obj is String) {
// `obj` is automatically cast to `String` in this branch
return obj.length
}

// `obj` is still of type `Any` outside of the type-checked branch
return null
}

or

1
2
3
4
5
6
fun getStringLength(obj: Any): Int? {
if (obj !is String) return null

// `obj` is automatically cast to `String` in this branch
return obj.length
}

or even

1
2
3
4
5
6
7
8
fun getStringLength(obj: Any): Int? {
// `obj` is automatically cast to `String` on the right-hand side of `&&`
if (obj is String && obj.length > 0) {
return obj.length
}

return null
}

See Classes - https://kotlinlang.org/docs/classes.html and Type casts - https://kotlinlang.org/docs/typecasts.html.

References

[1] Get started with Kotlin—Kotlin - https://kotlinlang.org/docs/basic-syntax.html

[2] Kotlin Programming Language - https://kotlinlang.org/