Освой Kotlin играючи

Сайт Александра Климова

Шкодим

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

Быстрое вступление

Исходный код хранится в файлах с расширением .kt (почему не .kot?).

В языке используется "кошачий принцип" - чем меньше печатаешь код, тем больше времени останется на сон.

Например, необязательно ставить точку с запятой в конце выражения. Так поступает JavaScript и многие новые языки программирования.


// и так сойдёт
val x = 1
val y = 2
В Kotlin есть единственное место, где точка с запятой обязательна - в перечислении enum

Необязательно объявлять тип переменной, если из контекста понятно её предназначение. Если брать предыдущий пример, то по значению 1 можно догадаться, что переменная является типом Int.

Узнать тип переменной в студии можно через комбинацию клавиш Ctrl+Shift+P

Kotlin не делит типы на примитивные и их обёртки. Например, есть тип Int вместо int и Integer.

Можно сразу вызывать println вместо длинного System.out.println. Стандартная библиотека Kotlin включает в себя популярные методы Java для быстрого доступа.

Например, можно быстро получить содержимое файла с сервера через метод URL.readText():


// не вызывать в основном потоке!
val address = "http://example.com"
val someText = URL(address).readText()

Объявление переменных

В Java мы сначала указываем тип переменной, а потом её имя. В Kotlin немного не так. Сначала вы указываете ключевое слово val или var, затем имя переменной и по желанию можете указать тип переменной.


val kitty = "Васька"
val age = 7
// необязательно, но укажем тип
val weight: Int = 3
val catName: String = "Мурзик"

val actionBar = supportActionBar // объект ActionBar в активности без new

Если вы не инициализируете переменную, то тип указать нужно обязательно.


val age: Int
age = 7

Иногда тип указывать обязательно.


val a: Any = 12
val context: Context = activity

Ключевое слово val (от слова value) ссылается на неизменяемую переменную, что соответствует ключевому слову final в Java.


// Java
final String name = "Васька";

// Kotlin
val name = "Васька"

А часто используемое выражение в Java можно заменить на конструкцию с ключевым словом const (применимо только к базовым типам):


// Java
public static final String CAT_TALK = "meow";

// Kotlin
const val CAT_TALK = "meow"

Для обычных изменяемых переменных используется ключевое слово var (от слова variable).

Рекомендуется всегда использовать val, если это позволяет логика программы.

При этом нужно помнить, что хотя ссылка val неизменяема, сам объект может быть изменяемым:


val cats = arrayListOf("Васька")
cats.add("Барсик")

При использовании var вы можете не указывать тип переменной, но это не значит, что вы можете использовать его не по назначению, это вам не PHP.


var answer = 42
// так нельзя
answer = "нет ответа"

Возникает вопрос, а в чём разница между val и const? В некоторых случаях поведение будем одинаковым, но есть разница в подходе. Мы можем использовать const для константы на этапе компиляции, а для val мы можем присвоить неизменяемое значение на этапе рантайма.


const val catName = "Мурзик" // можно
val catName = "Мурзик" // тоже можно

const val catName = getCompanyName() // нельзя, нужно сразу присвоить значение без вычислений
val catName = getCompanyName() // а так можно

Когда и где использовать val и const? Рассмотрим пример.


// какой-то класс
MyClass {
    companion object {    
        const val FILE_EXTENSION = ".png"    
        val FILENAME: String
        get() = "img_" + System.currentTimeMillis() + FILE_EXTENSION 
    }
}

Расширение класса можно считать константой. А имя файла вычисляется на основе времени и его нельзя использовать как константу.

Ключевое слово inline

Ещё одно новое ключевое слово в Kotlin.

Псевдоним для импорта

Чтобы не путаться с именами классов из разных пакетов, можно присвоить новый псевдоним.


import android.os.Bundle
import ru.alexanderklimov.cat.Bundle as CatBundle

fun getBundle() {
    val bundle1 = Bundle()
    val bundle2 = CatBundle()
}

typealias

Псевдоним типа позволяет определить для существующего типа альтернативное имя, которое может использоваться в коде. Если в вашем коде используется функциональный тип, например такой, как (Double) -> Double, — вы сможете определить псевдоним, который будет использоваться вместо этого типа, чтобы ваш код лучше читался. Псевдонимы типов определяются ключевым словом typealias.


typealias DoubleConversion = (Double) -> Double

При помощи typealias можно определять альтернативные имена для любых типов, не только функциональных. Например, следующее определение typealias CatArray = Array<Cat> позволяет обращаться к типу по имени CatArray вместо Array<Cat>.

Исключения

Создадим собственное исключение.


class CustomException(message:String): Exception(message)

Теперь можем кинуть созданное исключение в своём коде в нужном месте.


throw CustomException("Threw custom exception")
Реклама