Spec-Zone.ru › Kotlin 1.7

Идиомы

Коллекция случайных и часто используемых идиом в 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 { // 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()

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)

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

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

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

Что дальше?

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

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

Последнее изменение: 06 сентября 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