0% found this document useful (0 votes)
18 views

Introduction To Kotlin

You should probably get to work!

Uploaded by

carlgray8719
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views

Introduction To Kotlin

You should probably get to work!

Uploaded by

carlgray8719
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 26

Kotlin

Introduction
to Kotlin

@kotlin | Developed by JetBrains


Why Kotlin?

● Expressiveness/Conciseness
● Safety
● Portability/Compatibility
● Convenience
● High Quality IDE Support
● Community
● Android 👀
● More than a gazillion devices run Java Kotlin
● Lactose free
● Sugar free
● Gluten free
Logo
Name

Kotlin is named after an island in the Gulf of Finland.


Hello, world!

fun main(args: Array<String>) {


println("Hello, world!")
}

fun main() {
println("Hello, world!")
}

fun main() = println("Hello, world!")

Where is “;”???
The basics

fun main(args: Array<String>) {


print("Hello")
println(", world!")
}

● An entry point of a Kotlin application is the main top-level function.


● It accepts a variable number of String arguments that can be omitted.
● print prints its argument to the standard output.
● println prints its arguments and adds a line break.
Variables

val/var myValue: Type = someValue


● var - mutable
● val - immutable
● Type can be inferred in most cases
● Assignment can be deferred

val a: Int = 1// immediate assignment

var b = 2 // 'Int' type is inferred


b=a // Reassigning to 'var' is okay

val c: Int // Type required when no initializer is provided


c=3 // Deferred assignment
a=4 // Error: Val cannot be reassigned
Variables

const val/val myValue: Type = someValue


● const val - compile-time const value
● val - immutable value
● for const val use uppercase for naming

const val NAME = "Kotlin" // can be calculated at compile-time


val nameLowered = NAME.lowercase() // cannot be calculated at compile-time
Functions

fun sum(a: Int, b: Int): Int { Single expression function.


return a + b Unit means that the function does not
} return anything meaningful.
It can be omitted.
fun mul(a: Int, b: Int) = a * b
Arguments can have default values.

fun printMul(a: Int, b: Int): Unit {


println(mul(a, b))
}

fun printMul1(a: Int = 1, b: Int) {


println(mul(a, b))
}

fun printMul2(a: Int, b: Int = 1) = println(mul(a, b))


If expression

fun maxOf(a: Int, b: Int): Int { fun maxOf(a: Int, b: Int) =


is the same as
if (a > b) { if (a > b) {
return a a
} else { } else {
return b b
} }
}

if can be an expression (it can return).

Can be a one-liner:

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


When expression

when (x) { when {


1 -> print("x == 1") x < 0 -> print("x < 0")
2 -> print("x == 2") x > 0 -> print("x > 0")
else -> { else -> {
print("x is neither 1 nor 2") print("x == 0")
} }
} }

when returns, the same way that if does.


The condition can be inside of the
branches.
When statement

fun serveTeaTo(customer: Customer) {


val teaSack = takeRandomTeaSack()

when (teaSack) {
is OolongSack -> error("We don't serve Chinese tea like $teaSack!")
in trialTeaSacks, teaSackBoughtLastNight ->
error("Are you insane?! We cannot serve uncertified tea!")
}

teaPackage.brew().serveTo(customer)
}

when can accept several options in one branch. else branch can be omitted if when block is
used as a statement.
&& vs and

if (a && b) { ... } VS if (a and b) { ... }


Unlike the && operator, this function does not perform short-circuit evaluation.

The same behavior with OR:


if (a || b) { ... } VS if (a or b) { ... }
Loops

val items = listOf("apple", "banana", "kiwifruit")

for (item in items) {


println(item)
}

for (index in items.indices) {


println("item at $index is ${items[index]}")
}

for ((index, item) in items.withIndex()) {


println("item at $index is $item")
}
Loops

val items = listOf("apple", "banana", "kiwifruit")

var index = 0
while (index < items.size) {
println("item at $index is ${items[index]}")
index++
}

var toComplete: Boolean


do {
...
toComplete = ...
} while(toComplete)

The condition variable can be initialized inside to the do…while loop.


Loops

There are break and continue labels for loops:

myLabel@ for (item in items) {


for (anotherItem in otherItems) {
if (...) break@myLabel
else continue@myLabel
}
}
Ranges

val x = 10
if (x in 1..10) {
println("fits in range")
}

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

for (x in 9 downTo 0 step 3) {


print(x)
}

downTo and step are extension functions, not keywords.


'..' is actually T.rangeTo(that: T)
Null safety

val notNullText: String = "Definitely not null"


val nullableText1: String? = "Might be null"
val nullableText2: String? = null

fun funny(text: String?) {


if (text != null)
println(text)
else
println("Nothing to print :(")
}

fun funnier(text: String?) {


val toPrint = text ?: "Nothing to print :("
println(toPrint)
}
Elvis operator ?:

If the expression to the left of ?: is not null, the Elvis operator


returns it; otherwise, it returns the expression to the right.
Note that the expression on the right-hand side is evaluated
only if the left-hand side is null.

fun loadInfoById(id: String): String? {


val item = findItem(id) ?: return null
return item.loadInfo() ?: throw Exception("...")
}
Safe Calls

someThing?.otherThing does not throw an NPE if someThing is null.

Safe calls are useful in chains. For example, an employee may be assigned to a department
(or not). That department may in turn have another employee as a department head, who
may or may not have a name, which we want to print:

fun printDepartmentHead(employee: Employee) {


println(employee.department?.head?.name)
}

To print only for non-null values, you can use the safe call operator together with let:

employee.department?.head?.name?.let { println(it) }
Unsafe Calls

The not-null assertion operator (!!) converts any value to a non-null type and throws an NPE
exception if the value is null.

fun printDepartmentHead(employee: Employee) {


println(employee.department!!.head!!.name!!)
}

Please, avoid using unsafe


calls!
TODO

Always throws a NotImplementedError at run-time if called, stating that operation is not


implemented.

// Throws an error at run-time if calls this function, but compiles


fun findItemOrNull(id: String): Item? = TODO("Find item $id")

// Does not compile at all


fun findItemOrNull(id: String): Item? = { }
String templates and the string builder

val i = 10
val s = "Kotlin"

println("i = $i")
println("Length of $s is ${s.length}")

val sb = StringBuilder()
sb.append("Hello")
sb.append(", world!")
println(sb.toString())
Lambda expressions

val sum: (Int, Int) -> Int = { x: Int, y: Int -> x + y }


val mul = { x: Int, y: Int -> x * y }

According to Kotlin convention, if the last parameter of a function is a function, then a lambda
expression passed as the corresponding argument can be placed outside the parentheses:

val badProduct = items.fold(1, { acc, e -> acc * e })

val goodProduct = items.fold(1) { acc, e -> acc * e }

If the lambda is the only argument, the parentheses can be omitted entirely (the
documentation calls this feature "trailing lambda as a parameter"):

run({ println("Not Cool") })


run { println("Very Cool") }
When in doubt

Go to:
● kotlinlang.org
● kotlinlang.org/docs
● play.kotlinlang.org/byExample
Thanks!

@kotlin | Developed by JetBrains

You might also like