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

Introduction to Kotlin

Introduction to Kotlin

Showing the power of Kotlin including basic syntax and functional approach. Kotlin User Group Bosnia first meetup.

Bajic Dusko

October 04, 2017
Tweet

More Decks by Bajic Dusko

Other Decks in Programming

Transcript

  1. What? • JVM based language • Statically-typed (type inference) •

    Usage of functional programming concepts • Null safe(r) • Expressive • Awesome IDE support - IntelliJ
  2. Why? • Why not? • Android developers are in pain

    • Java 8, 9? Nope, Java7. • Port libraries • JVM - bytecode - Kotlin (Groovy, Scala, Clojure) • Highly interoperable with Java
  3. Basics name val public String getName() { return name; }

    = "John" final String name = "John"; private private String name = "John" public String getName() { return name; } public void setName(String name){ this.name = name; } name var = "John" user.name = "Jane" val tempName = user.name
  4. var name: String get() = field.toUpperCase() set(value){ field = "Name:

    $value" } val isAndroid: Boolean get() os == "Android" = //class Device if(device.isAndroid){ //do something } Basics
  5. class User { } (username: String, displayName: String) init {

    log.debug("Yay $username is created") } constructor(profile: Profile) : this(profile.username, profile.displayName){ } construcutor open class Admin : User("admin", "ADMIN") { } val admin = Admin() Basics
  6. data class User(val firstName: String, val lastName: String, val isAdmin:

    Boolean = false) class User{ private String firstName; private String lastName; private boolean isAdmin; public User(String firstName, String lastName, boolean isAdmin){ this.firstName = firstName; this.lastName = lastName; this.isAdmin = isAdmin; } public User(String firstName, String lastName){ this(firstName, lastName, false); } //getters and setters for all fields } Basics
  7. interface Tappable { fun tap() } class View : Tappable

    fun click() = println("I'm clicked") override fun tap(){
 if(touchEvent.duration in 1..100){
 //do something
 } } } else {
 click()
 } val area: Area override val area: Area = Area(10, 40) { Basics
  8. Flow control: "if" •If is an expression •There is no

    ternary operator var res = if (x > y) x else y var res = if(x > y){ println("Result is $x") x } else { println("Result is $y") y }
  9. Flow control: "when" •Replaces switch statement •Matching an argument sequentially

    against all branches •Is also an expression. Matching branch is returned. •Else block is required (in most cases)
  10. Flow control: "when" when(x) { 2 -> println("Correct result is

    2") 4 -> println("Correct result is 4") else -> { println("Wrong result is $x") } } when(x) { in 1..10 -> println("Result is in safe range") 11, 12 -> println("Result is 11 or 12") else -> { println("Result $x is out of range") } }
  11. Flow control: "for(each)" val numbers = listOf(1, 2, 3, 4)

    for(n in numbers){ println(n) } for(n in 1..100){ println(n) } for(index in ){
 println(index) } 0 until users.size for(index in 100 downTo 1 ){
 println(index) } step 2
  12. Functions fun stringSize(value: String): Int { return value.length } fun

    printStringSize(value: String) println("Size ${value.length}") =
  13. Functions var list = emptyList<Int>() var list = listOf(1, 2,

    3) println(list.last()) // 3 println(list.max()) // 3 println(list.sortedDescending()) // [3, 2, 1] println(joinToString(list, prefix = "# ", suffix = ";")) //# 1, 2, 3; var users = mutableListOf(User(18), User(22)) println(users.sortedBy({ it.age })) //User(age = 18), User(age = 22) println(users.sortedBy({ it.age }).map({ it.age }) //18, 22
  14. Extension Functions • Util hell • Adding methods to other

    people's classes • We're good as long as it is compiled to Java class fun String.lastChar(): Char = this.get(this.length - 1) Receiver type Function name Receiver object fun String.lastChar(): Char = get(length - 1) import some_package_name.lastChar println("John".lastChar()) val String.lastChar: Char = get() = get(length - 1) println("John".lastChar)
  15. Extension Functions public class ViewUtil{ public static void fadeIn(Button button){

    button.setAlpha(0F) button.setVisibility(View.VISIBLE) button.animate().alpha(1F).duration(250).start() } } ViewUtil.fadeIn(button)
  16. Extension Functions fun View.fadeIn(){ alpha = 0F visibility = View.VISIBLE

    animate().alpha(1F).duration(250).start() } button.fadeIn()
  17. Nullability • "Unfortunately, the application X has stopped" - java.lang.NullPointerException

    • Goal: Converting runtime errors into compile-time errors • Introduced nullable types var name: String = null var name: String? = null fun stringSize(value: String ) = value .length ? ? ?: 0 Int
  18. Nullability var car: Car? = Tesla("Model 3") fun energySource(car: Car)

    = if (car.battery.kwhEnergy >= 60) "Electricity" else "Unknown" val energySource = energySource(car)
  19. Nullability var car: Car? = Tesla("Model 3") fun energySource(car: Car)

    = if (car.battery.kwhEnergy >= 60) "Electricity" else "Unknown" val energySource = energySource(car) if(car != null){ }
  20. if (car.battery.kwhEnergy >= 60) "Electricity" else "Unknown" Nullability var car:

    Car = Tesla("Model 3") fun energySource(car: Car?) = val energySource = energySource(car)
  21. Nullability var car: Car = Tesla("Model 3") fun energySource(car: Car?)

    = val energySource = energySource(car) if (car?.battery?.kwhEnergy ?: 0 >= 60) "Electricity" else "Unknown"
  22. Nullability var car: Car = Tesla("Model 3") fun energySource(car: Car?)

    = val energySource = energySource(car) if (car battery kwhEnergy >= 60) "Electricity" else "Unknown" !! !!
  23. High-Ordered Functions • Function that takes another function as an

    argument or returns one • Function types val sum: (Int, Int) -> Int = { x, y -> x + y } Parameter Types Return Type val sum = { x: Int, y: Int -> x + y } Int
  24. High-Ordered Functions val sum = { x: Int, y: Int

    -> x + y } val div = { x: Int, y: Int -> x / y } val mul = { x: Int, y: Int -> x * y } fun <T : Number> execute(opOne: T, opTwo: T, opFn: (T, T) -> T) = opFn(opOne, opTwo) val sumRes = execute(2, 3, sum) val multiplicationResult = execute(2, 3, mul) val divideResult = execute(2, 3, div)
  25. High-Ordered Functions lateinit var pref: Pref val editor = pref.edit()

    editor.putString("name", "John") editor.apply() fun Editor.applyChange(execute: (Editor) -> Unit){
 execute(this)
 apply()
 } typealias SharedPreferences = Pref
 typealias SharedPreferences.Editor = Editor
  26. High-Ordered Functions lateinit var pref: Pref val editor = pref.edit()

    editor.putString("name", "John") editor.apply() fun Editor.applyChange(execute: (Editor) -> Unit){
 execute(this)
 apply()
 } typealias SharedPreferences = Pref
 typealias SharedPreferences.Editor = Editor pref.edit().applyChange { .putString("name", "John") } editor -> editor
  27. High-Ordered Functions lateinit var pref: Pref fun Editor.applyChange(execute: (Editor) ->

    Unit){
 execute(this)
 apply()
 } pref.edit().applyChange { .putString("name", "John")} it
  28. High-Ordered Functions lateinit var pref: Pref val editor = edit()


    execute(editor)
 editor.apply()
 } -> Unit){ fun Pref.applyChange(execute: (Editor).() pref.applyChange { putString("name", "John")}
  29. High-Ordered Functions lateinit var pref: Pref val editor = edit()


    execute(editor)
 editor.apply()
 } -> Unit){ fun Pref.applyChange(execute: (Editor).() fun Pref.save( ){ when(value){ is String -> putString(key, value) else -> throw NotMappedTypeException(value) } } applyChange { } val (value, key) = valueKeyFn() valueKeyFn: () -> Pair<Any, String> pref.save { "John" to "name" }
  30. High-Ordered Functions SharedPreferences.Editor editor = sharedPreferences.edit() editor.putString("name", "John") editor.apply() SharedPreferences.Editor

    editor = sharedPreferences.edit() editor.putString("age", 29) editor.apply() SharedPreferences.Editor editor = sharedPreferences.edit() editor.putBoolean("adminStatus", false) editor.apply() cache.save { "John" to "name" } cache.save { 29 to "age" } cache.save { false to "adminStatus" }