Kotlin на практике

96
на практике Виталий Бендик [email protected] Android Software Engineer, PlanetPass
  • Upload

    -
  • Category

    Software

  • view

    125
  • download

    0

Transcript of Kotlin на практике

Page 1: Kotlin на практике

на практике

Виталий Бендик [email protected]

Android Software Engineer, PlanetPass

Page 2: Kotlin на практике

План• О Kotlin

• Основные фичи

• Kotlin для

• Ресурсы

• Вопросы

2

Page 3: Kotlin на практике

План• О Kotlin

• Основные фичи

• Kotlin для

• Ресурсы

• Вопросы

3

Page 4: Kotlin на практике

О Kotlin• Прагматичный

• Выразительный

• Безопасный

• 100% совместим с Java

• Статически типизированный

• Мультипарадигмальный

4

Page 5: Kotlin на практике

О Kotlin• Прагматичный

• Выразительный

• Безопасный

• 100% совместим с Java

• Статически типизированный

• Мультипарадигмальный

5

Page 6: Kotlin на практике

Прагматичный

6

• Не исследовательский язык

• Не принуждает использовать определённую парадигму или стиль

• Нацелен на инструментарий (IDE)

Page 7: Kotlin на практике

Выразительныйpublic class HelloCodingMonday {

public static void main(String[] args) { System.out.println("Hello, Coding Monday!"); }

}

7

Page 8: Kotlin на практике

Выразительныйfun main (args: Array<String>) { println("Hello, Coding Monday!") }

8

Page 9: Kotlin на практике

Выразительныйpublic int sum(int a, int b) { return a+b; }

9

Page 10: Kotlin на практике

Выразительный

10

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

Page 11: Kotlin на практике

Выразительный

11

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

Page 12: Kotlin на практике

Выразительный

12

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

Page 13: Kotlin на практике

Выразительныйpublic class Cat { String name; int age; }

13

Page 14: Kotlin на практике

Выразительныйpublic class Cat { private String name; private int age; }

14

Page 15: Kotlin на практике

Выразительныйpublic class Cat { private String name; private int age;

public String getName() { return name; }

public void setName(String name) { this.name = name; }

public int getAge() { return age; }

public void setAge(int age) { this.age = age; } }

15

Cat cat = new Cat(); cat.setName("Meow"); cat.setAge(1);

Cat cat = new Cat("Meow", 1);

Page 16: Kotlin на практике

Выразительныйpublic class Cat { private String name; private int age;

public Cat(String name, int age) { this.name = name; this.age = age; }

public String getName() { return name; }

public void setName(String name) { this.name = name; }

public int getAge() { return age; }

public void setAge(int age) { this.age = age; } }

16

Page 17: Kotlin на практике

Выразительный

17

class Cat(var name: String?, var age: Int)

Page 18: Kotlin на практике

Безопасный

18

• NullPointerException

• ClassCastException

Page 19: Kotlin на практике

Безопасный

19

• NullPointerException

• ClassCastException

Page 20: Kotlin на практике

Безопасный

20

var s1:String = "Hello, Coding Monday"

Page 21: Kotlin на практике

Безопасный

21

var s1:String = "Hello, Coding Monday"

println(s1.toUpperCase()) // Всё ок

Page 22: Kotlin на практике

Безопасный

22

var s1:String = "Hello, Coding Monday"

println(s1.toUpperCase()) // Всё ок

s1 = null // Ошибка компиляции

Page 23: Kotlin на практике

Безопасный

23

var s2:String? = null

Page 24: Kotlin на практике

Безопасный

24

var s2:String? = "Hello, Coding Monday"

println(s2.toUpperCase()) // Ошибка компиляции

Page 25: Kotlin на практике

Безопасный

25

var s2:String? = "Hello, Coding Monday"

println(s2?.toUpperCase()) // Всё ок

Page 26: Kotlin на практике

Безопасный

26

var s2:String? = "Hello, Coding Monday"

println(s2?.toUpperCase()) // Всё ок

println(null)

Page 27: Kotlin на практике

Безопасный

27

var s2:String? = "Hello, Coding Monday"

println(s2?.toUpperCase()) // Всё ок

println(null)

if (s2 != null) { println(s2.toUpperCase()) // Всё ок }

Page 28: Kotlin на практике

Безопасныйpublic void onClick(View view) { if (view instanceof TextView) { ((TextView) view).setText("Hello, Coding Monday!"); } }

28

Page 29: Kotlin на практике

Безопасный

29

fun onClick(view: View) { if (view is TextView) { view.text = "Hello, Coding Monday!" } }

Page 30: Kotlin на практике

100% совместим с Java

30

• Любой код на Java доступен в Kotlin

• Работает в обе стороны

• Код на Kotlin и Java в одном проекте

• Использует стандартную библиотеку Java

Page 31: Kotlin на практике

План• О Kotlin

• Основные фичи

• Kotlin для

• Ресурсы

• Вопросы

31

Page 32: Kotlin на практике

Основные фичи• Выведение типов • Значения по умолчанию • Именованные параметры

• Data классы

• Деструктуризация

• Функции расширения

• Инфиксные функции

• Свойства (атрибуты)

• Лямбды

• Лямбда-ресиверы

• when, if

32

Page 33: Kotlin на практике

Выведение типовpublic class BookCafe {

public void takeCoffee(int count) { // реализация }

}

33

Page 34: Kotlin на практике

Выведение типовclass BookCafe {

fun takeCoffee(count: Int): Unit { // реализация }

}

34

Page 35: Kotlin на практике

Выведение типовclass BookCafe {

fun takeCoffee(count: Int) { // реализация }

}

35

Page 36: Kotlin на практике

Выведение типовpublic class HelloCodingMonday {

public static void main(String[] args) { int a = 1; int b = 2; int c = a + b; }

}

36

Page 37: Kotlin на практике

Выведение типовfun main (args: Array<String>) { var a: Int = 1 var b: Int = 2 var c: Int = a + b }

37

Page 38: Kotlin на практике

Выведение типовfun main (args: Array<String>) { var a = 1 var b = 2 var c = a + b }

38

Page 39: Kotlin на практике

Основные фичи• Выведение типов • Значения по умолчанию • Именованные параметры

• Data классы

• Деструктуризация

• Функции расширения

• Инфиксные функции

• Свойства (атрибуты)

• Лямбды

• Лямбда-ресиверы

• when, if

39

Page 40: Kotlin на практике

Значения по умолчаниюclass BookCafe {

fun takeCoffee(count: Int) { // реализация }

}

40

// Где-то в коде val bookCafe = BookCafe() bookCafe.takeCoffee(3)

Page 41: Kotlin на практике

Значения по умолчаниюclass BookCafe {

fun takeCoffee(count: Int = 1) { // реализация }

}

41

// Где-то в коде val bookCafe = BookCafe() bookCafe.takeCoffee(3)

Page 42: Kotlin на практике

Значения по умолчаниюclass BookCafe {

fun takeCoffee(count: Int = 1) { // реализация }

}

42

// Где-то в коде val bookCafe = BookCafe() bookCafe.takeCoffee() // по умолчанию count = 1

Page 43: Kotlin на практике

Основные фичи• Выведение типов • Значения по умолчанию • Именованные параметры

• Data классы

• Деструктуризация

• Функции расширения

• Инфиксные функции

• Свойства (атрибуты)

• Лямбды

• Лямбда-ресиверы

• when, if

43

Page 44: Kotlin на практике

Именованные параметрыclass BookCafe {

fun takeCoffee(count: Int = 1, milk: Boolean = false) { // реализация }

}

44

// Где-то в коде val bookCafe = BookCafe() bookCafe.takeCoffee(true) // Ошибка компиляции

Page 45: Kotlin на практике

Именованные параметрыclass BookCafe {

fun takeCoffee(count: Int = 1, milk: Boolean = false) { // реализация }

}

45

// Где-то в коде val bookCafe = BookCafe() bookCafe.takeCoffee(milk = true) // count = 1

Page 46: Kotlin на практике

Основные фичи• Выведение типов • Значения по умолчанию • Именованные параметры

• Data классы

• Деструктуризация

• Функции расширения

• Инфиксные функции

• Свойства (атрибуты)

• Лямбды

• Лямбда-ресиверы

• when, if

46

Page 47: Kotlin на практике

Data классыpublic class Cat { private String name; private int age;

public Cat(String name, int age) { this.name = name; this.age = age; }

public String getName() { return name; }

public void setName(String name) { this.name = name; }

public int getAge() { return age; }

public void setAge(int age) { this.age = age; } }

47

Page 48: Kotlin на практике

Data классыpublic class Cat { private final String name; private final int age;

public Cat(String name, int age) { this.name = name; this.age = age; }

public String getName() { return name; }

public int getAge() { return age; } }

48

Page 49: Kotlin на практике

Data классыpublic class Cat { private final String name; private final int age;

public Cat(String name, int age) { this.name = name; this.age = age; }

public String getName() { return name; }

public int getAge() { return age; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Cat cat = (Cat) o; if (age != cat.age) return false; return name != null ? name.equals(cat.name) : cat.name == null; } }

49

Page 50: Kotlin на практике

Data классыpublic class Cat { private final String name; private final int age;

public Cat(String name, int age) { this.name = name; this.age = age; }

public String getName() { return name; }

public int getAge() { return age; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Cat cat = (Cat) o; if (age != cat.age) return false; return name != null ? name.equals(cat.name) : cat.name == null; } @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + age; return result; } }

50

Page 51: Kotlin на практике

Data классыpublic class Cat { private final String name; private final int age;

public Cat(String name, int age) { this.name = name; this.age = age; }

public String getName() { return name; }

public int getAge() { return age; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Cat cat = (Cat) o; if (age != cat.age) return false; return name != null ? name.equals(cat.name) : cat.name == null; } @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + age; return result; }

@Override public String toString() { return “Cat(" + "name='" + name + '\'' + ", age=" + age + ‘)'; } }

51

Page 52: Kotlin на практике

Data классы

52

data class Cat(val name: String?, val age: Int)

Page 53: Kotlin на практике

Основные фичи• Выведение типов • Значения по умолчанию • Именованные параметры

• Data классы

• Деструктуризация

• Функции расширения

• Инфиксные функции

• Свойства (атрибуты)

• Лямбды

• Лямбда-ресиверы

• when, if

53

Page 54: Kotlin на практике

Деструктуризацияval cat = Cat("Meow", 3) val (name, age) = cat

println("name = " + name) println("age = " + age)

54

component1() component2()

Page 55: Kotlin на практике

Деструктуризацияval cat = Cat("Meow", 3) val (name, age) = cat

println("name = " + name) println("age = " + age)

55

name = Meow age = 3

component1() component2()

Page 56: Kotlin на практике

Деструктуризацияval map = mapOf("One" to 1, "Two" to 2, "Three" to 3) for ((key, value) in map) { println(key + " = " + value)}

56

One = 1 Two = 2 Three = 3

Page 57: Kotlin на практике

Основные фичи• Выведение типов • Значения по умолчанию • Именованные параметры

• Data классы

• Деструктуризация

• Функции расширения

• Инфиксные функции

• Свойства (атрибуты)

• Лямбды

• Лямбда-ресиверы

• when, if

57

Page 58: Kotlin на практике

Функции расширенияfun ImageView.loadUrl(url: String) { Picasso.with(context).load(url).into(this) }

58

override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) ...

val img = findViewById(R.id.photo) as ImageView img.loadUrl("http://placekitten.com/g/200/300") }

Page 59: Kotlin на практике

Функции расширения

59

public final class ImageUtil { public static final void loadUrl(@NotNull ImageView img, @NotNull String url) { Picasso.with(img.getContext()).load(url).into(img); }}

Page 60: Kotlin на практике

Основные фичи• Выведение типов • Значения по умолчанию • Именованные параметры

• Data классы

• Деструктуризация

• Функции расширения

• Инфиксные функции

• Свойства (атрибуты)

• Лямбды

• Лямбда-ресиверы

• when, if

60

Page 61: Kotlin на практике

Инфиксные функции

61

infix fun Int.add(a:Int) = this+a

fun main (args: Array<String>) { println(1.add(10)) }

Page 62: Kotlin на практике

Инфиксные функции

62

infix fun Int.add(a:Int) = this+a

fun main (args: Array<String>) { println(1 add 10) }

Page 63: Kotlin на практике

Инфиксные функции

63

val map = mapOf("One" to 1, "Two" to 2, "Three" to 3) for ((key, value) in map) { println("$key = $value") }

Page 64: Kotlin на практике

Инфиксные функции

64

val map = mapOf("One" to 1, "Two" to 2, "Three" to 3) for ((key, value) in map) { println(key + " = " + value)}

infix fun String.to(that: Int): Pair<String, Int> { return Pair(this, that) }

Page 65: Kotlin на практике

Основные фичи• Выведение типов • Значения по умолчанию • Именованные параметры

• Data классы

• Деструктуризация

• Функции расширения

• Инфиксные функции

• Свойства (атрибуты)

• Лямбды

• Лямбда-ресиверы

• when, if

65

Page 66: Kotlin на практике

Свойства (атрибуты)

66

class Cat(val name: String?, var age: Int)

Page 67: Kotlin на практике

Свойства (атрибуты)

67

class Cat { val name: String? var age: Int constructor(name: String?, age: Int) { this.name = name this.age = age }}

Page 68: Kotlin на практике

Свойства (атрибуты)

68

class main (args: Array<String>) { val cat = Cat("Meow", 2) println("cat's age = ${cat.age}")

cat.age = 100 println("cat's age = ${cat.age}") }

cat's age = 2 cat's age = 100

Page 69: Kotlin на практике

Свойства (атрибуты)

69

class Cat { val name: String? var age: Int constructor(name: String?, age: Int) { this.name = name this.age = age }}

Page 70: Kotlin на практике

Свойства (атрибуты)

70

class Cat { val name: String? var age: Int set(value) { if (value in 1..20) field = value } constructor(name: String?, age: Int) { this.name = name this.age = age }}

Page 71: Kotlin на практике

Свойства (атрибуты)

71

class main (args: Array<String>) { val cat = Cat("Meow", 2)

cat.age = 100 println("cat's age = ${cat.age}") cat.age = 5 println("cat's age = ${cat.age}") }

cat's age = 2 cat's age = 5

Page 72: Kotlin на практике

Основные фичи• Выведение типов • Значения по умолчанию • Именованные параметры

• Data классы

• Деструктуризация

• Функции расширения

• Инфиксные функции

• Свойства (атрибуты)

• Лямбды

• Лямбда-ресиверы

• when, if

72

Page 73: Kotlin на практике

Лямбды

73

(1..10).filter { n -> n % 2 == 0 }.map { n -> println(n) }

2 4 6 8 10

Page 74: Kotlin на практике

Лямбды

74

(1..10).filter { it % 2 == 0 }.map { n -> println(n) }

2 4 6 8 10

Page 75: Kotlin на практике

Лямбды

75

(1..10).filter { it % 2 == 0 }.map(::println)

2 4 6 8 10

Page 76: Kotlin на практике

Лямбда-ресиверы

76

fun buildString(f: StringBuilder.() -> Unit): String { val sb = StringBuilder() sb.f() return sb.toString()}

Hello, Coding Monday

fun main (args: Array<String>) { val s = buildString({ append("Hello, ") append("Coding Monday") }) println(s) }

Page 77: Kotlin на практике

Лямбда-ресиверы

77

fun buildString(f: StringBuilder.() -> Unit): String { val sb = StringBuilder() sb.f() return sb.toString()}

Hello, Coding Monday

fun main (args: Array<String>) { val s = buildString { append("Hello, ") append("Coding Monday") } println(s) }

Page 78: Kotlin на практике

Основные фичи• Выведение типов • Значения по умолчанию • Именованные параметры

• Data классы

• Деструктуризация

• Функции расширения

• Инфиксные функции

• Свойства (атрибуты)

• Лямбды

• Лямбда-ресиверы

• when, if

78

Page 79: Kotlin на практике

when

79

val x = (Math.random() * 100).toInt()when (x) { 0 -> println("$x is zero") 1,2,3 -> println("$x is equals 1 or 2 or 3") in 4..50 -> println("$x in range: 4..50") is Int -> println("$x is Int") else -> println("$x is unknown") }

Page 80: Kotlin на практике

when

80

fun checkX(x: Int) = when (x) { 0 -> "$x is zero" 1,2,3 -> "$x is equals 1 or 2 or 3" in 4..50 -> "$x in range: 4..50" is Int -> "$x is Int" else -> "$x is unknown"}

val x = (Math.random() * 100).toInt()println(checkX(x))

Page 81: Kotlin на практике

if

81

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

val a = (Math.random() * 100).toInt()val b = (Math.random() * 100).toInt()println("Max of $a and $b is ${max(a, b)}")

Page 82: Kotlin на практике

План• О Kotlin

• Основные фичи

• Kotlin для

• Ресурсы

• Вопросы

82

Page 83: Kotlin на практике
Page 84: Kotlin на практике

Как это работает?

84

Page 85: Kotlin на практике

Подготовка проекта• Создаём проект "как обычно" (с пустой Activity)

• ⌥⇧⌘K или в меню Code → Convert Java File to Kotlin File

• Меню Tools → Kotlin → Configure Kotlin in Project

• Синхронизируем Gradle

• Профит!

85

Page 86: Kotlin на практике

Полезные библиотеки• Kotlin Android Extensions

• apply plugin: 'kotlin-android-extensions'

• Anko

• https://github.com/Kotlin/anko

• Spek

• https://github.com/JetBrains/spek

• Kodein

• https://github.com/SalomonBrys/Kodein

86

Page 87: Kotlin на практике

План• О Kotlin

• Основные фичи

• Kotlin для

• Ресурсы

• Вопросы

87

Page 88: Kotlin на практике

Ресурсы

Page 89: Kotlin на практике

Ссылки• https://kotlinlang.org/docs/reference/

• http://try.kotlinlang.org

• https://kotlin.link

• https://t.me/kotlinized

89

Page 90: Kotlin на практике

Книги

Page 91: Kotlin на практике

Dmitry Jemerov Svetlana Isakova

Kotlin in Action

91

Page 92: Kotlin на практике

Antonio Leiva

Kotlin for Android Developers

92

Page 93: Kotlin на практике

Чаты• [ru] https://t.me/kotlin_lang

• [en] https://kotlinlang.slack.com

93

Page 94: Kotlin на практике

План• О Kotlin

• Основные фичи

• Kotlin для

• Ресурсы

• Вопросы

94

Page 95: Kotlin на практике

Вопросы?https://github.com/bendikv

https://twitter.com/vitaliy_bendikhttps://linkedin.com/in/bendikv

Page 96: Kotlin на практике

Всем Котлина!