С тех пор, как я переехал в Котлин, я ни разу не оглядывался назад!

Прежде, чем мы начнем

Я использую Kotlin некоторое время и считаю, что у него есть правильный набор функций для разработчиков. Я расскажу о функциях, которые действительно хорошо работали как для Spring Boot Backend, так и для Android. Но прежде чем перейти к этому, давайте начнем с основ.

Что такое Котлин?

Kotlin - это универсальный статически типизированный язык программирования с открытым исходным кодом для JVM, браузера, Native и Android, который сочетает в себе функции объектно-ориентированного и функционального программирования.

Интересный факт

Название происходит от острова Котлин, недалеко от Санкт-Петербурга. Андрей Бреслав упомянул, что команда решила назвать его в честь острова, так же как Ява была названа в честь индонезийского острова Ява.

Еще несколько фактов

  • Рост Kotlin удваивался каждый год до 2015 года, когда произошел первый значительный всплеск его использования.
  • Google объявил, что Kotlin официально поддерживается для Android, и огромное количество разработчиков Android начали использовать Kotlin.
  • Инструмент сборки Gradle серьезно к этому относится.
  • Старожилы вроде Spring поддерживают Котлина
  • В официальных исследованиях, проведенных JetBrains, было задано два вопроса, и это были результаты.

1. Как вы в основном используете Kotlin?

2. Что мешает вам использовать Kotlin в производстве?

Хорошо видно, что многие люди уже начали использовать его в производстве. И основная причина, по которой люди не используют его, - это недостаток знаний. Я надеюсь, что это сообщение в блоге поможет снизить процент «нехватки знаний» и сделает людей более комфортными при использовании Kotlin в производственной среде.

Нулевая безопасность - это благословение

Это одна из лучших особенностей Kotlin. Это сокращает накладные расходы на разработчика и заставляет писать безопасный код. Система типов Kotlin направлена ​​на устранение опасности нулевых ссылок из кода, также известной как Ошибка на миллиард долларов.

У нас все еще могут быть поля, которые могут быть null, но мы должны явно заявить об этом, и именно поэтому компилятор всегда будет жаловаться, если вы не обработаете его должным образом.

Проблема с NPE (исключение нулевого указателя) заключается в его способности проникать в кодовую базу. И чаще всего ваше приложение бросает его во время выполнения, когда ваши пользователи фактически используют приложение.

С безопасным оператором ?. вы можете легко справиться с этим явным образом.

Java 
 if (text != null) { 
   int length = text.length(); 
 } 
 
Kotlin 
 text?.let { 
     val length = text.length 
 } 
 // or simply 
 val length = text?.length

А для обработки нулевого случая вы можете использовать оператор Элвиса ?:

val result = nullableVariable?.someMethodCall()
                       ?: fallbackIfNullMethodCall()

Запечатанные классы для ограниченных иерархий

Запечатанные классы - это способ Kotlin предоставить вам способ ограничить типы класса, когда значение может иметь один из типов из ограниченного набора.

sealed class Operation {
    class Add(val value: Int) : Operation()
    class Substract(val value: Int) : Operation()
}

А затем просто используйте выражение when для оценки условий для каждого из типов. Если вы пропустите какой-либо тип, компилятор пожалуется. Это уменьшает объем кода, который вы пишете.

fun execute(x: Int, op: Operation) = when (op) {
    is Operation.Add -> x + op.value
    is Operation.Substract -> x - op.value
}

Большинство серверных баз кода будут иметь своего рода отслеживание аналитики для отслеживания поведения ваших пользователей или системы. Использование запечатанных классов для создания набора событий, которые вы запускаете, было бы хорошим способом гарантировать, что все события имеют согласованный формат. Тогда выражение when гарантирует, что вы не пропустили ни одного из событий во время компиляции.

Еще одно хорошее использование запечатанных классов в Android - обработка состояний пользовательского интерфейса. Допустим, у вас есть три состояния для вашей активности: Загрузка, Данные, Нет данных. Вы можете создать запечатанный класс UIState и обрабатывать его в действии. Подробнее об использовании запечатанных классов для Android вы можете узнать здесь.

Неизменяемость - настройка по умолчанию

В Kotlin мы всегда должны использовать val для объявления переменной. Это создает неизменяемую переменную. В Java мы должны добавить дополнительное ключевое слово final (опять же, синтаксический шум!). Если ваша переменная действительно должна быть изменяемой, вы можете использовать var. Но подумайте дважды, прежде чем использовать var.

val immutableName = "Name"
immutableName = "New name" // compile error! 
var mutableName = "Name"
mutableName = "New Name"

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

Как и ссылки на переменные, коллекции неизменяемы по умолчанию, как и классы данных.

val list = listOf(1,2,3,4) 
list.add(1) //compile error.

У вас все еще есть изменяемые коллекции, которые можно объявить с префиксом изменяемые перед коллекцией.

val list = mutableListOf(1,2,3,4)
list.add(1)

Поздняя инициализация свойств

Модификатор lateinit позволяет отложить инициализацию переменной. Очень полезно, когда зависимости инициализируются структурой DI (внедрение зависимостей), что происходит во время выполнения.

Это очень удобно для тестирования, так как большинство классов имитируются. Как и в случае с Spring Boot, когда ваши зависимости предоставляются Spring.

@Mock
lateinit var myRepository: MyRepository

Если вы используете Dagger, вы можете использовать фрагменты кода, подобные следующему:

@Inject
lateinit var myVar: MyObject

На самом деле переменная не инициализируется, а вводится позже. Используя lateinit, мы позволяем инициализацию происходить позже. Это уменьшает количество ненужных нулевых проверок.

Меньше шаблонов - определенно плюс

Это один из первых аргументов в пользу Kotlin. Kotlin сокращает объем кода, который вы пишете и никогда не просматриваете. Он очень хорошо разработан для основных случаев использования. Например, классы данных легко предоставляют функции equals, hashCode, toString и копирования.

// Java
public class Price {
    String amount;
    String currency;

    public Price(String amount, String currency) {
        this.amount = amount;
        this.currency = currency;
    }

    public String getAmount() {
        return amount;
    }

    public void setAmount(String amount) {
        this.amount = amount;
    }

    public String getCurrency() {
        return currency;
    }

    public void setCurrency(String currency) {
        this.currency = currency;
    }
}
// Kotlin
data class Price(val amount: String, val currency: String)

Несколько вещей, о которых следует знать

  • Я столкнулся с несколькими проблемами при использовании Hibernate с Kotlin, потому что по умолчанию все классы final. Чтобы обойти это, вам нужно добавить несколько зависимостей и плагинов. Вот ссылка с подробной информацией.
  • Затенение имен иногда действительно может превратиться в кошмар, и это всего лишь предупреждения компилятора. Когда ваш код становится слишком вложенным, его становится труднее читать.
  • Kotlin проделал хорошую работу по сокращению стандартного кода и сделал все кратким, но это иногда приводит к очень высокой плотности информации.

Последние мысли

Чем больше я пишу приложения на Kotlin, тем комфортнее мне с ним. Это позволило мне более эффективно писать приложения с выразительным, коротким и читаемым кодом, и пользоваться им было настоящим удовольствием.

И, как и любой другой язык, когда вы запускаете его впервые, он кажется запутанным и чуждым. Но Котлин выглядел наименее запутанным, большинство конструкций было довольно легко понять и запомнить. Я работал в Java, Go и немного на Python , но на сегодняшний день это мой самый любимый.

Я настоятельно рекомендую изучить его и использовать.

Другие интересные сообщения в блоге!







Ссылки на популярные концепции Kotlin.

  1. Стандартные функции Kotlin
  2. var, val, lateinit, lazy
  3. Запечатанный класс для Android
  4. Использование финальных классов с Hibernate