Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Kotlin in 45 minutes

44a168e6578c2cc83aaf54a38458ade9?s=47 Magda Miu
November 09, 2019

Kotlin in 45 minutes

Kotlin promises concise, expressive and secure code. The presentation will include a full tour of language basics, we will have some fun with functions and will learn new keywords from the Kotlin world. We will discover the main advantages of Kotlin compared to Java and we will explore the inventive features Kotlin offers for working with classes. Finally, we will highlight some advanced topics like delegation and coroutines. This talk is suitable for every developer who is looking for a modern and safe language to use in developing awesome apps.

44a168e6578c2cc83aaf54a38458ade9?s=128

Magda Miu

November 09, 2019
Tweet

Transcript

  1. Kotlin in 45 minutes Magda Miu @magdamiu Squad Lead Developer

    at Orange Android Google Developer Expert
  2. 1 4 3 2 Agenda Introduction Kotlin Basics Functions Classes

    5 Kotlin Essentials
  3. 1 4 3 2 Agenda Introduction Kotlin Basics Functions Classes

    5 Kotlin Essentials
  4. What is Kotlin? • General-purpose • FP + OOP •

    Open source (Apache 2.0) • Developed by JetBrains • Static typing
  5. Kotlin Philosophy To create a modern and pragmatic language for

    the industry, not an academic one.
  6. 2010 Project started 2016 Kotlin 1.0 2017 Official on Android

    2018 Kotlin 1.3 2019 Kotlin 1.3.50 Kotlin timeline
  7. Kotlin popularity In the latest Stack Overflow developer survey, it

    ranks as the 4th most loved programming language.
  8. Current adoption

  9. Build Applications for...

  10. Android apps built with Kotlin

  11. Conventions • The same conventions like on Java • Uppercase

    for types • Lower camelCase for methods and properties • Semicolons are optional • Reverse notation for packages ◦ A file could contain multiple classes ◦ The folder names not have to match the package name
  12. Development tools • JDK ◦ JVM 1.6+ • Kotlin Compiler

    • Editor or IDE ◦ IntelliJ IDEA, Android Studio, NetBeans, Eclipse
  13. *.kt *.java Kotlin compiler Java compiler *.class *.jar App Kotlin

    is 100% interoperable with Java Kotlin runtime
  14. Build tools • Maven • Gradle • Kobalt • Ant

    • Command Line
  15. 1 4 3 2 Agenda Introduction Kotlin Basics Functions Classes

    5 Kotlin Essentials
  16. Basic Types Type Size Double 64 Float 32 Long 64

    Int 32 Short 16 Byte 8
  17. val vs var • val is immutable (read-only) and you

    can only assign a value to them exactly one time. • var is mutable and can be reassigned. // immediate assignment val countOfEvenNumbers: Int = 10 // `Int` type is inferred var sumOfNumbers = 0 // type required when no initializer is provided var countOfPrimeNumbers: Int // deferred assignment countOfPrimeNumbers = 3 countOfPrimeNumbers = 24
  18. String interpolation • Simple reference uses $ • Complex references

    uses ${} • Raw Strings """ val firstWord = "Learn " val secondWord = "Kotlin" var bothWords = "$firstWord $secondWord" println("$bothWords has ${bothWords.length}") println(""""$bothWords" has ${bothWords.length}""")
  19. Control flow: if, when, for, while • if - in

    Kotlin if is an expression, so it returns a value. There is no ternary operator. • when - replaces “switch” from Java. We can also check a value for being or not in a specific range and we can also check if a variable is or not of a particular type. • for - iterates through anything that provides an iterator. Can use the withIndex library function. • while and do … while - same behaviour like in Java.
  20. val number = 0 val result = if (number >

    0) { "Positive number" } else if (number < 0) { "Negative number" } else { "Zero" } println(result) if / else
  21. val number = 0 val result = if (number >

    0) { "Positive number" } else if (number < 0) { "Negative number" } else { "Zero" } println(result) // => Zero if / else
  22. val firstValue = 6 val secondValue = 3 val operator

    = "/" val resultOfOperation = when (operator) { "+" -> firstValue + secondValue "-" -> firstValue - secondValue "*" -> firstValue * secondValue "/" -> firstValue / secondValue else -> "$operator operator is invalid." } println(resultOfOperation) when
  23. val firstValue = 6 val secondValue = 3 val operator

    = "/" val resultOfOperation = when (operator) { "+" -> firstValue + secondValue "-" -> firstValue - secondValue "*" -> firstValue * secondValue "/" -> firstValue / secondValue else -> "$operator operator is invalid." } println(resultOfOperation) // => 2 when
  24. var age = 22 when (age) { in 1..18 ->

    print("Age is in the range") !in 18..110 -> print("Age is outside the range") else -> print("None of the above") } when with range
  25. var age = 22 when (age) { in 1..18 ->

    print("Age is in the range") !in 18..110 -> print("Age is outside the range") else -> print("None of the above") } // => None of the above when with range
  26. var sum = 234 when (sum) { is Int ->

    println("The sum is $sum") else -> println("It is not an Int") } when with check type
  27. var sum = 234 when (sum) { is Int ->

    println("The sum is $sum") else -> println("It is not an Int") }// => The sum is 234 when with check type
  28. for (index in 1..10) { println(index) } for (index in

    12 downTo 0 step 2) { println(index) } for
  29. var languages = arrayOf("Java", "Kotlin", "Scala", "C#") for (item in

    languages) println(item) var desserts = arrayOf("Cupcake", "Ice cream", "Eclair", "Pie") for (item in desserts.indices) { if (desserts[item].length > 4) println(desserts[item]) } for with index
  30. while (sumOfNumbers > 0) { sumOfNumbers-- } do { val

    result = retrieveData() } while (result != null) while & do... while
  31. Equality Checks In Kotlin we have structural equality (a check

    for equals()) == val countries = setOf("Java", "JavaScript", "Swift") val neighbors = setOf("Swift", "JavaScript", "Java") println(countries == neighbors) // => true
  32. None
  33. Null safety • In an effort to rid the world

    of NullPointerException, variable types in Kotlin don't allow the assignment of null. • In order to use a variable that can be null, declare it nullable by adding ? at the end of its type.
  34. But wait... The only possible causes of NPE's may be:

    • An explicit call to throw NullPointerException() • Usage of the !! operator (not-null assertion operator) • Some data inconsistency with regard to initialization • Java interoperation
  35. // check for null in conditions val trainingName: String? =

    "Learn Kotlin in 45 minutes" if (trainingName != null && trainingName.isNotEmpty()) { print("String of length ${trainingName.length}") } else { print("Empty string") }
  36. val platform: String? = null val language = "Kotlin" println(platform?.length)

    // safe call println(language.length) // unnecessary safe call val lengthOfWord = platform!!.length // !! operator val numberOfLetters: Int? = lengthOfWord as? Int // safe cast
  37. val platform: String? = null val language = "Kotlin" println(platform?.length)

    // safe call println(language.length) // unnecessary safe call val lengthOfWord = platform!!.length // !! operator val numberOfLetters: Int? = lengthOfWord as? Int // safe cast
  38. val platform: String? = null val language = "Kotlin" println(platform?.length)

    // safe call println(language.length) // unnecessary safe call val lengthOfWord = platform!!.length // !! operator val numberOfLetters: Int? = lengthOfWord as? Int // safe cast
  39. // Elvis operator val name: String? = null val lengthOfName

    = name?.length ?: -1 println(lengthOfName)
  40. // Elvis operator val name: String? = null val lengthOfName

    = name?.length ?: -1 println(lengthOfName) // => -1
  41. 1 4 3 2 Agenda Introduction Kotlin Basics Functions Classes

    5 Kotlin Essentials
  42. Let’s have some fun

  43. // Kotlin syntax for main function fun main() { println("Hello

    Kotlin!") }
  44. fun add(a: Int, b: Int): Int { return a +

    b } Function name Parameters Return type Function body
  45. // equivalent Kotlin syntax fun add(a: Int, b: Int): Int

    { return a + b } fun add(a: Int, b: Int): Int = a + b fun add(a: Int, b: Int) = a + b
  46. // equivalent Kotlin syntax fun add(a: Int, b: Int): Int

    { return a + b } fun add(a: Int, b: Int): Int = a + b fun add(a: Int, b: Int) = a + b
  47. // equivalent Kotlin syntax fun add(a: Int, b: Int): Int

    { return a + b } fun add(a: Int, b: Int): Int = a + b fun add(a: Int, b: Int) = a + b
  48. // default parameter values fun displayTitleAndName(name: String, prefix: String =

    "dr") { println("$prefix $name") }
  49. // named arguments fun getFullName(firstName: String, lastName: String): String {

    return "$firstName $lastName" } getFullName(lastName = "Miu", firstName = "Magda")
  50. class Utility { // infix functions = functions with a

    single parameter infix fun String.onto(other: String) = Pair(this, other) } fun main(args: Array<String>) { val blueShoes = "blue".onto("shoes") val yellowScarf = "yellow" onto "scarf" println(blueShoes) // => (blue, shoes) println(yellowScarf) // => (yellow, scarf) }
  51. // functions with varargs parameters fun varargExample(vararg names: Int) {

    println("Argument has ${names.size} elements") } varargExample() // => Argument has 0 elements varargExample(1) // => Argument has 1 elements varargExample(1, 2, 3) // => Argument has 3 elements
  52. // high order function = fun with fun or fun

    returns a fun fun add(a: Int, b: Int): Int { return a + b } fun returnAddFunction(): ((Int, Int) -> Int) { return ::add }
  53. Lambda • A lambda expression or an anonymous function is

    a “function literal”, i.e. a function that is not declared, but passed immediately as an expression • A lambda expression is always surrounded by curly braces • Its parameters (if any) are declared before -> (parameter types may be omitted) • The body goes after -> (when present)
  54. val sum: (Int, Int) -> Int = { a, b

    -> a + b } println(sum(3,4))
  55. val sum: (Int, Int) -> Int = { a, b

    -> a + b } println(sum(3,4)) // => 7
  56. // returning from a lambda val calculateGrade = { grade

    : Int -> when(grade) { in 0..40 -> "Fail" in 41..70 -> "Pass" in 71..100 -> "Distinction" else -> false } } println(calculateGrade(57))
  57. // returning from a lambda val calculateGrade = { grade

    : Int -> when(grade) { in 0..40 -> "Fail" in 41..70 -> "Pass" in 71..100 -> "Distinction" else -> false } } println(calculateGrade(57)) // => Pass
  58. Extension functions • An extension function is a member function

    of a class that is defined outside the class. • Extensions are resolved statically and can also be defined with the class type that is nullable. • If a class contains a companion object, then we can also define extension functions and properties for the companion object.
  59. fun String.removeFirstLastChar(): String = this.substring(1, this.length - 1) Receiver type

    Receiver object
  60. fun String.removeFirstLastChar(): String = this.substring(1, this.length - 1) println("Kotlin".removeFirstLastChar())

  61. fun String.removeFirstLastChar(): String = this.substring(1, this.length - 1) println("Kotlin".removeFirstLastChar()) //

    => otli
  62. 1 4 3 2 Agenda Introduction Kotlin Basics Functions Classes

    5 Kotlin Essentials
  63. fun reportError(): Nothing { throw RuntimeException() } fun displayHelloMessage(): Unit

    { println("Hello from Kotlin! :)") }
  64. fun reportError(): Nothing { throw RuntimeException() } fun displayHelloMessage(): Unit

    { println("Hello from Kotlin! :)") }
  65. Basic Data Types Numbers Characters Booleans Arrays Strings Any Nothing

    Unit
  66. Class • There are primary and secondary constructors. For secondary

    we should add the keyword constructor • The primary constructor cannot contain any code.
  67. // primary constructor with fullName property (setter & getter) class

    Person(val fullName: String) { /*...*/ }
  68. class Person(val fullName: String) { val age: Int get() {

    return 18 } // secondary constructor constructor(fullName: String, age: Int) : this(fullName) {} } // instance of the class val john = Person("John", 24)
  69. Package Visibility modifiers Modifier Description public declarations are visible everywhere

    (default one) private visible inside the file containing the declaration internal visible inside the same module (a set of Kotlin files compiled together) Class Modifier Description public visible to any client who can see the declaring class private visible inside the class only protected visible inside the class and its subclasses internal visible to any client inside the module that can see the declaring class
  70. Inheritance • Inheritance: use open keyword for class • Overriding

    methods and properties: use the open modifier open class Person { open val name = "Tom" open fun displaySkills() { } } // inheritance and override class Student : Person() { override val name = "Jerry" override fun displaySkills(){ } }
  71. // "object" keyword can be used to create singleton objects.

    object TheObject { fun hello() = "hello" override fun toString() = "Hello, it's me, ${TheObject::class.simpleName}" } fun useSingletonObject() { println(TheObject.hello()) // => hello val someRef: Any = TheObject println(someRef) // => Hello, it's me, TheObject }
  72. Abstract class • An abstract class cannot be instantiated. •

    We can override a non-abstract open member with an abstract one • Abstract class or abstract function does not need to annotate with open keyword as they are open by default.
  73. abstract class Car { abstract fun run() open fun computeTaxes()

    {} } abstract class SafeCar: Car() { override fun run() { println("SafeCar is running safely..") } override abstract fun computeTaxes() }
  74. Interface • An interface can have both abstract and non-abstract

    functions. • An interface can only have abstract properties (data members) • A class can implement more than one interface. • All abstract properties and abstract functions of an interface must be overridden in the classes that implement it.
  75. interface Pet { fun eat() fun sleep() } class Cat

    : Pet { override fun eat() { println("Cat eats fish") } override fun sleep() { println("Cat sleeps a lot") } }
  76. Delegation • Composition over Inheritance design pattern • Native support

    for delegation (implicit delegation) • Zero boilerplate code
  77. interface PetAction { fun eat() } interface PetColor { val

    color: String } object YellowColor : PetColor { override val color = "yellow" }
  78. class PrintingPetAction(val food: String) : PetAction { override fun eat()

    { println(food) } } class Cat(petColor: PetColor = YellowColor) : PetAction by PrintingPetAction("eats a lot of fish"), PetColor by petColor
  79. class PrintingPetAction(val food: String) : PetAction { override fun eat()

    { println(food) } } class Cat(petColor: PetColor = YellowColor) : PetAction by PrintingPetAction("eats a lot of fish"), PetColor by petColor
  80. fun delegate() { val kittyCat = Cat() println("Pet has color

    ${kittyCat.color}") kittyCat.eat() } fun main(args: Array<String>) { delegate() } // => Pet has color yellow // => eats a lot of fish
  81. • Data classes are a concise way to create classes

    that just hold data. Data classes Function Price Getters and Setters 0 Lei equals() & hashCode() 0 Lei toString() 0 Lei componentN() 0 Lei copy() 0 Lei TOTAL FREE!
  82. data class Character(val name: String, val age: Int) fun main()

    { val mickeyMouse = Character("Mickey Mouse", 82) val mickeyMouseToday = mickeyMouse.copy(age = 83) // destructuring declarations val (name, age) = mickeyMouseToday println("$name, $age years of age") mickeyMouseToday.component1() // => name mickeyMouseToday.component2() // => age }
  83. Companion object • companion object: syntactically it's similar to the

    static methods in Java class Person { companion object { fun callMe() = "Call" } } // Person.callMe()
  84. 1 4 3 2 Agenda Introduction Kotlin Basics Functions Classes

    5 Kotlin Essentials
  85. Collections

  86. None
  87. // immutable list and mutable list val numbersList = listOf("one",

    "two", "three") val mutableNumbersList = mutableListOf("one", "two", "three") listOf(1, 5, 3).sum() // => 9 listOf("a", "b", "cc").sumBy { it.length } // => 4 List
  88. // immutable set and mutable set val colors = setOf("red",

    "blue", "yellow") val mutableColors = mutableSetOf("red", "blue", "yellow") val longerThan3 = colors.filter { it.length > 3 } // => [blue, yellow] Set
  89. // immutable map and mutable map val desserts = hashMapOf("whipped

    cream" to "cake", "chocolate" to "cookie") println(desserts["chocolate"]) val inventory = mutableMapOf("pancake" to 1) inventory.put("cake", 3) inventory.remove("pancake") Map
  90. // Sequences represent lazily-evaluated collections. val fooSequence = generateSequence(1, {

    it + 1 }) val x = fooSequence.take(10).toList() println(x) // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] Sequence
  91. Collection vs Sequence Source: Collections and sequences in Kotlin by

    Florina Muntenescu
  92. Coroutines

  93. Coroutines are lightweight threads

  94. Coroutines = Co + Routines Cooperation Functions

  95. Single threaded Thread 1 Task 1 Task 2 Task 3

    Task 4
  96. Multiple threaded Thread 1 Task 1 Task 3 Thread 2

    Task 2 Task 4
  97. Coroutine Thread 1 Task 1 Task 3 Thread 2 Task

    2 Task 4 Result
  98. Suspend functions • suspend is a keyword that defines the

    coroutine and it means that the function could be paused or resumed • Used inside coroutines like regular functions • Can call other suspending functions • Wait tasks to complete
  99. Builders • launch - Launches new coroutine without blocking current

    thread and returns a reference to the coroutine as a Job. • runBlocking - Runs new coroutine and blocks current thread interruptible until its completion. • async - Creates new coroutine and returns its future result as an implementation of Deferred. We can use await to get the result.
  100. Hello Kotlin import kotlinx.coroutines.* fun main() = runBlocking { launch

    { printKotlin() } println("Hello") } suspend fun printKotlin() { delay(1000L) println("Kotlin") } Example 1
  101. Kotlin Hello import kotlinx.coroutines.* fun main() = runBlocking { printKotlin()

    println("Hello") } suspend fun printKotlin() { delay(1000L) println("Kotlin") } Example 1
  102. Main advantages of Kotlin • Readability ◦ A code is

    clean if it is easy to understand • Interoperability ◦ Q: “Can I use my existing libraries?” ◦ A: “Yes, absolutely!” • Safety ◦ Prevents some specific type of errors (NPE) • Tooling ◦ Kotlin is a compiled language (IntelliJ IDEA, Android Studio, NetBeans, Eclipse)
  103. Best practices 1. Agree on conventions beforehand 2. Don’t treat

    it as Java with a different syntax 3. Use a linter (like ktlint) 4. Embrace the immutability 5. Reconsider if you need to use !! operator 6. Don’t hide too much info 7. Choose readable over short expressions
  104. Kotlin is about developer happiness and productivity.

  105. Learn more...

  106. None
  107. None
  108. None
  109. Thank you! Magda Miu @magdamiu Squad Lead Developer at Orange

    Android Google Developer Expert