Дорогие читатели,
Помогите сделать документацию лучше!

К сожалению текст все еще содержит некоторое количество ошибок, и мы просим вас найти и исправить их. Если бы каждый из посетителей исправил хотя бы одну ошибку, то мы смогли бы довести до совершенства весь материал всего за один день.


Идиомы

Набор различных часто используемых идиом в языке Kotlin. Если у вас есть любимая идиома, вы можете поделится ею здесь. Для этого нужно выполнить pull request.

Создание DTO (он же POJO или POCO)

data class Customer(val name: String, val email: String)

создаёт класс Customer, обладающий следующими возможностями:

  • геттеры (и сеттеры в случае var's) для всех свойств
  • метод equals()
  • метод hashCode()
  • метод toString()
  • метод copy()
  • методы component1(), component2(), и т.п. для всех свойств (см. Классы данных)

Значения по умолчанию для параметров функций

fun foo(a: Int = 0, b: String = "") { ... }

Фильтрация списка

val positives = list.filter { x -> x > 0 }

Или короче:

val positives = list.filter { it > 0 }

Форматирование строк

println("Name $name")

Проверка объекта на принадлежность к определённому классу

when (x) {
    is Foo -> ...
    is Bar -> ...
    else   -> ...
}

Итерация по карте/списку пар

for ((k, v) in map) {
    println("$k -> $v")
}

Имена переменных k и v не имеют значения

Использование последовательностей чисел

for (i in 1..100) { ... }
for (x in 2..10) { ... }

Read-only список

val list = listOf("a", "b", "c")

Read-only ассоциативный список (map)

val map = mapOf("a" to 1, "b" to 2, "c" to 3)

Обращение к ассоциативному списку

println(map["key"])
map["key"] = value

Ленивые свойства

val p: String by lazy {
    // compute the string
}

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

fun String.spaceToCamelCase() { ... }

"Convert this to camelcase".spaceToCamelCase()

Создание синглтона

object Resource {
    val name = "Name"
}

Сокращение для "Если не null"

val files = File("Test").listFiles()

println(files?.size)

Сокращение для "Если не null, иначе"

val files = File("Test").listFiles()

println(files?.size ?: "empty")

Вызов оператора при равенстве null

val data = ...
val email = data["email"] ?: throw IllegalStateException("Email is missing!")

Выполнение при неравенстве null

val data = ...

data?.let {
    ... // execute this block if not null
}

Return с оператором when

fun transform(color: String): Int {
    return when (color) {
        "Red" -> 0
        "Green" -> 1
        "Blue" -> 2
        else -> throw IllegalArgumentException("Invalid color param value")
    }
}

'try/catch' как выражение

fun test() {
    val result = try {
        count()
    } catch (e: ArithmeticException) {
        throw IllegalStateException(e)
    }

    // Working with result
}

'if' как выражение

fun foo(param: Int) {
    val result = if (param == 1) {
        "one"
    } else if (param == 2) {
        "two"
    } else {
        "three"
    }
}

Builder-style использование методов, возвращающих Unit

fun arrayOfMinusOnes(size: Int): IntArray {
    return IntArray(size).apply { fill(-1) }
}

Функции, состоящие из одного выражения

fun theAnswer() = 42

Что равносильно этому:

fun theAnswer(): Int {
    return 42
}

Для сокращения кода их можно эффективно совмещать с другими идиомами. Например с when:

fun transform(color: String): Int = when (color) {
    "Red" -> 0
    "Green" -> 1
    "Blue" -> 2
    else -> throw IllegalArgumentException("Invalid color param value")
}

Вызов нескольких методов объекта ('with')

class Turtle {
    fun penDown()
    fun penUp()
    fun turn(degrees: Double)
    fun forward(pixels: Double)
}

val myTurtle = Turtle()
with(myTurtle) { //draw a 100 pix square
    penDown()
    for(i in 1..4) {
        forward(100.0)
        turn(90.0)
    }
    penUp()
}

try with resources из Java 7

val stream = Files.newInputStream(Paths.get("/some/file.txt"))
stream.buffered().reader().use { reader ->
    println(reader.readText())
}