Spec-Zone.ru › Kotlin 1.9

Идиомы

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

Создание 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-ended range: includes 100
for (i in 1..<100) { ... } // open-ended 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 { // the value is computed only on first access
    // 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()

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

// To calculate a more complicated fallback value in a code block, use `run`
val filesSize = files?.size ?: run { 
    val someSize = getSomeSize()
    someSize * 2
}
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)

Возможный null boolean

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, поэтому она может использоваться независимо от ожидаемого типа. Также есть перегрузка, принимающая параметр reason:

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

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

Что дальше?

  • Решите задачи Advent of Code с использованием стилистики Kotlin.

  • Узнайте, как выполнить типичные задачи со строками в Java и Kotlin.

  • Узнайте, как выполнить типичные задачи с коллекциями в Java и Kotlin.

  • Узнайте, как обрабатывать возможность null в Java и Kotlin.

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

© 2010–2023 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