Spec-Zone.ru › Kotlin 1.6

Идиомы

Сборник случайных и часто используемых идиом в Kotlin. Если у вас есть любимая идиома, внесите её, отправив запрос на добавление.

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

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

предоставляет класс Customer со следующей функциональностью:

  • геттеры (и сеттеры в случае var) для всех свойств

  • 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 }

Узнайте разницу между фильтрацией в Java и Kotlin.

Проверка наличия элемента в коллекции

if ("john@example.com" in emailsList) { ... }

if ("jane@example.com" !in emailsList) { ... }

Интерполяция строк

println("Name $name")

Узнайте разницу между конкатенацией строк в Java и Kotlin.

Проверка типов объектов

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

Список только для чтения

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

Словарь только для чтения

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

Доступ к элементу словаря

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

Проход по словарю или списку пар

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

k и v могут быть любыми удобными именами, такими как name и age.

Итерация по диапазону

for (i in 1..100) { ... }  // closed range: includes 100
for (i in 1 until 100) { ... } // half-open range: does not include 100
for (x in 2..10 step 2) { ... }
for (x in 10 downTo 1) { ... }
(1..10).forEach { ... }

Отложенное свойство

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

Расширяющие функции

fun String.spaceToCamelCase() { ... }

"Convert this to camelcase".spaceToCamelCase()

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

object Resource {
    val name = "Name"
}

Создание экземпляра абстрактного класса

abstract class MyAbstractClass {
    abstract fun doSomething()
    abstract fun sleep()
}

fun main() {
    val myObject = object : MyAbstractClass() {
        override fun doSomething() {
            // ...
        }

        override fun sleep() { // ...
        }
    }
    myObject.doSomething()
}

Краткая запись для проверки на не-null

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

println(files?.size) // size is printed if files is not null

Краткая запись для проверки на не-null с альтернативой

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

println(files?.size ?: "empty") // if files is null, this prints "empty"

// To calculate the fallback value in a code block, use `run`
val filesSize = files?.size ?: run { 
    return someSize 
}
println(filesSize)

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

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

Получение первого элемента из потенциально пустой коллекции

val emails = ... // might be empty
val mainEmail = emails.firstOrNull() ?: ""

Узнайте разницу между получением первого элемента в Java и Kotlin.

Выполнение, если не null

val value = ...

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

Преобразование значения, если оно не null

val value = ...

val mapped = value?.let { transformValue(it) } ?: defaultValue 
// defaultValue is returned if the value or the transform result is null.

Возврат в операторе 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

val y = if (x == 1) {
    "one"
} else if (x == 2) {
    "two"
} else {
    "other"
}

Использование методов, возвращающих 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()
}

Настройка свойств объекта с помощью apply

val myRectangle = Rectangle().apply {
    length = 4
    breadth = 5
    color = 0xFAFAFA
}

Это полезно для настройки свойств, которые отсутствуют в конструкторе объекта.

Try-with-resources Java 7

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

Обобщенная функция, требующая информацию о типе обобщения

//  public final class Gson {
//     ...
//     public <T> T fromJson(JsonElement json, Class<T> classOfT) throws JsonSyntaxException {
//     ...

inline fun <reified T: Any> Gson.fromJson(json: JsonElement): T = this.fromJson(json, T::class.java)

Переменная Boolean, которая может быть null

val b: Boolean? = ...
if (b == true) {
    ...
} else {
    // `b` is false or null
}

Перестановка двух переменных

var a = 1
var b = 2
a = b.also { b = a }

Отметить код как неполный (TODO)

Стандартная библиотека Kotlin имеет функцию TODO(), которая всегда вызывает исключение NotImplementedError. Её тип возвращаемого значения Nothing, поэтому она может использоваться независимо от ожидаемого типа. Также есть перегрузка, принимающая параметр причины:

fun calcTaxes(): BigDecimal = TODO("Waiting for feedback from accounting")

Плагин kotlin для IntelliJ IDEA понимает семантику TODO() и автоматически добавляет указатель на код в окно TODO.

Что дальше?

  • Решите задачи Advent of Code в стиле idiomatic Kotlin

  • Научитесь выполнять типичные задачи со строками в Java и Kotlin

Последнее изменение: 07 апреля 2022
Основные синтаксические конструкции Рекомендации по написанию кода

© 2010–2022 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/idioms.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API