Рубрики
Без рубрики

Котлин: Руководство и учебник для начинающих

Учебное пособие: Изучите основы Kotlin, создав приложение, и узнайте, почему разработчики Java любят Kotlin!. С тегами kotlin, java, учебник, безопасность.

Kotlin – это современный, статически типизированный язык в JVM. Kotlin – это кроссплатформенный, многоцелевой, бесплатный язык с открытым исходным кодом, разработанный JetBrains по лицензии Apache 2.0 и имеющий конструкции как для объектно-ориентированного, так и для функционального стилей программирования, которые могут быть смешанными. Его можно использовать для веб-разработки, серверной и клиентской, а также мобильной разработки с использованием большинства Java IDE.

Kotlin – отличный вариант для разработчиков Java, потому что он лаконичен, выразителен и безопасен. По оценкам JetBrains, это может сократить общее количество строк кода в вашем приложении до 40 процентов. Котлин также помогает предотвратить Исключение NullPointerException s, поскольку он предоставляет не обнуляемые типы.

Согласно Отчету GitHub за октябрь 2018 года , Kotlin является самым быстрорастущим языком номер один. С 2,2 млн пользователей его популярность растет с каждым месяцем, и им пользуются крупные компании. Разработчики Android и JVM влюбляются в его функции. Давайте узнаем, почему.

В этом посте вы найдете:

  • Обзор функций Kotlin
  • Руководство по созданию приложения “Привет, мир!” и решению основной задачи алгоритма
  • Быстрый шаг за шагом для запуска загрузочного приложения Kotlin Spring с аутентификацией через Okta

Чтобы пройти полный курс обучения, вам понадобятся следующие инструменты:

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

Котлин против Java, он же Зачем этот учебник?

Kotlin был разработан для устранения ряда проблем Java:

Нулевые ссылки : Java допускает нулевые ссылочные значения, и, как видно выше, система типов Kotlin помогает исключить доступ к элементу нулевой ссылки, что приведет к эквиваленту исключения NullPointerException .

Инвариантный массив : В Java массивы ковариантны, а массив Целое число[] является подтипом Числа[] , поэтому компилятор позволяет назначать Удваивайте до Числа[] ссылки, но программа может вызвать исключение во время выполнения, если экземпляр является Целым числом[] . Котлин не позволяет вам назначать Массив<Строка> в Массив <Любой> , предотвращающий сбои во время выполнения. Любой является корнем иерархии классов Котлина.

// Compiles but will raise java.lang.ArrayStoreException
Integer[] intArray = new Integer[1];
Number[] numberArray = intArray;
numberArray = intArray;
numberArray[0] = 1.0;

В Котлине:

var intArray = arrayOf(1)
var numArray = arrayOf(1.0)
numArray = intArray // Compiler error Type mismatch

Любой является корнем иерархии классов Kotlin, но он не эквивалентен Объект . Однако/|java.lang. Объект сопоставлен с котлином. Любой! , и ! обозначение означает, что это может быть Любой или Какие-нибудь? (обнуляется или нет). Как Объект , другие типы Java не используются "как есть", а сопоставляются с типами Kotlin. Полный список сопоставлений доступен в справочнике Котлин .

Нет необработанных типов : В Котлине нет необработанных типов, так как дженерики разные. Необработанные типы Java, например Список , преобразуется в проекции звезд Список<*>! , которые похожи на необработанные типы, но обеспечивают безопасность во время выполнения. Как? Компилятор не разрешит операции записи, если аргумент типа неизвестен, так как это может вызвать исключение приведения при чтении. В Java вы можете добавить любой объект в необработанный список, но в Kotlin добавление в начальный проецируемый список не будет компилироваться.

Дисперсия использования сайта : Система типов Java использует ограниченные подстановочные знаки для повышения гибкости API, поскольку универсальные типы инвариантны (в отличие от массивов Java, которые являются ковариантными), что означает List<Строка> не является подтипом List<Объект> , но может быть присвоен List расширяет объект> тип. В Котлине, вместо ограниченных подстановочных знаков, разница в использовании сайта позволяет ограничить универсальный тип в том месте, где он используется, с более простым синтаксисом, таким как Массив <из любого> , эквивалентный массиву Java расширяет объект> . расширяет объект> . Компилятор проверяет, что тип параметра возвращается только из метода экземпляра, но не используется, чтобы избежать исключений во время выполнения, например, при попытке написать Строка для Массив

package com.okta.developer

fun main() {
    val a = arrayOf("uno", "dos", "tres")
    readMethod(a)
}

fun readMethod(a: Array) {
    println(a[0])
    a.set(0, 1) // Out-projected type prohibits the use of fun set
}

Приведенный выше пример не компилируется в Kotlin, потому что метод read() получает исходящий массив (разрешены только операции чтения) и вызывает операцию записи установить() .

Нет проверенных исключений : проверенные исключения Java должны быть каким-то образом обработаны для компиляции программы и много раз проглатываются пустым блоком catch. В Kotlin нет проверенных исключений, поскольку предполагается, что в крупных программных проектах это снижает производительность.

Правильные типы функций : : В отличие от преобразований Java SAM (Единый абстрактный метод), где лямбда-выражение преобразуется в ОДИН и ТОТ же тип в соответствии с некоторыми правилами, Kotlin использует семейство типов функций, таких как (Int) ->Строка

Полный список функций Kotlin, не поддерживаемых в Java, доступен по ссылке Kotlin/|.

Совместимость Java и Kotlin

Kotlin на 100% совместим с Java, код Kotlin можно вызывать с Java и наоборот. Существующий код Java можно использовать с некоторыми соображениями, например, методы получения и установки Java представлены свойствами в Kotlin:

val calendar = Calendar.getInstance()
calendar.firstDayOfWeek = Calendar.MONDAY // setFirstOfWeek()

С помощью IDE, такой как IntelliJ IDEA, вы можете добавить исходный код Java в проект Kotlin, просто создав файл .java .

Объекты, поступающие из Java, называемые типами платформ , имеют ослабленные проверки на нуль по практическим соображениям, и безопасность такая же, как и в Java. Kotlin не сообщит об ошибке компиляции, но вызов может завершиться неудачно во время выполнения. Например, если Kotlin вызывает код Java, который возвращает ArrayList , выводимый тип в Kotlin будет ArrayList<Строка! >! , что означает, что коллекция может быть обнулена, а также элементы.

В приведенном ниже коде Java null добавляется в качестве элемента в список.

import java.util.ArrayList;

public class ArrayWithNulls {

    public static ArrayList create(){
        ArrayList strings = new ArrayList();
        strings.add(null);
        strings.add("foo");
        return strings;
    }
}

В приведенных ниже строках Kotlin мы вызываем предыдущий код Java, поэтому безопасность ослаблена. Программа компилируется, но в качестве первого элемента используется null , он выйдет из строя во время выполнения с Исключение IllegalStateException .

val list = ArrayWithNulls.create()
val item = list.get(0) // platform type inferred (ordinary Java object)
item.substring(1) // IllegalStateException: item must not be null

Предварительный урок: Вкус Котлина

Чтобы избежать проклятия программиста, давайте не будем пропускать попытку простого “Привет, мир!” пример с Котлином. Простой способ начать работу с Kotlin – загрузить и установить IntelliJ IDEA Community Edition с JetBrains, который также является бесплатным. А также установите Maven для управления зависимостями и запуска приложения из командной строки.

Запустите IntelliJ IDEA и создайте новый проект Kotlin, выбрав Kotlin/JVM .

Задайте имя проекта, местоположение и пакет SDK Java 8. После создания проекта добавьте поддержку Maven, щелкнув правой кнопкой мыши по проекту и выбрав Добавить поддержку платформы . Затем установите флажок Maven и нажмите ХОРОШО .

Переименовать src/main/java в src/main/котлин и src/тест/java в src/тест/котлин .

Добавьте новый файл/класс Kotlin в папку src/main/kotlin . Установите имя файла в приложение . Среда IDE автоматически добавит расширение .kt , что указывает на то, что это файл Kotlin. Добавьте следующий код:

package com.okta.developers

fun main() {
    println("Hello, World!")
}

В строках выше вы можете увидеть объявление пакета, которое является необязательным. Если его нет, все отправляется в пакет по умолчанию. Функция main является точкой входа в приложение и может быть объявлена без параметров (если вашей программе не нужно принимать аргументы командной строки) и ничего не возвращать. Функция println является частью стандартной библиотеки Kotlin и выводит сообщение и разделитель строк в стандартный поток вывода.

ПРИМЕЧАНИЕ : В Kotlin не требуется сопоставлять каталоги и пакеты. Исходные файлы могут быть размещены произвольно в файловой системе, и один файл может содержать несколько классов. Для чистых проектов Kotlin общий корневой пакет com.okta.developers отсутствует в файловой системе .

Отредактируйте свой pom.xml для добавления зависимостей Kotlin и плагина Kotlin Maven.



    4.0.0

    com.okta.developers
    kotlin-hello-world
    1.0-SNAPSHOT

    
        1.3.50
        4.12
        com.okta.developer.AppKt
    

    
        
            org.jetbrains.kotlin
            kotlin-stdlib
            ${kotlin.version}
        
        
            org.jetbrains.kotlin
            kotlin-test-junit
            ${kotlin.version}
            test
        
        
            junit
            junit
            ${junit.version}
            test
        
    

    
        ${project.basedir}/src/main/kotlin
        ${project.basedir}/src/test/kotlin
        
            
                org.jetbrains.kotlin
                kotlin-maven-plugin
                ${kotlin.version}

                
                    
                        compile
                        
                            compile
                        
                    

                    
                        test-compile
                        
                            test-compile
                        
                    
                
            
            
                org.apache.maven.plugins
                maven-jar-plugin
                2.6
                
                    
                        
                            true
                            ${main.class}
                        
                    
                
            
            
                org.codehaus.mojo
                exec-maven-plugin
                1.2.1
                
                    
                        
                            java
                        
                    
                
                
                    ${main.class}
                
            
        
    


Создайте и запустите приложение с помощью следующей команды Maven:

mvn package exec:java

Он должен вывести приветственное сообщение:

Hello, World!
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

Идиомы Котлина

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

Во-первых, обновите функцию main в app.kt , чтобы она сканировала строку для анализа из стандартного ввода:

package com.okta.developers

fun main() {
    val string = readLine()
    val result = string?.let { Anagrams().count(it) }

    println(result)
}

В приведенном выше коде мы объявляем две неизменяемые переменные, используя ключевое слово val . Изменяемые переменные должны быть объявлены с ключевым словом var . Котлин также делает вывод типа, так что, как вы можете видеть, ни одна из переменных не объявляет тип. Readline() – это функция из kotlin-stdlib , которая считывает строку из стандартного входного потока, доступного для JVM и собственных целевых объектов.

Затем добавьте новый файл/класс Kotlin в существующий проект с именем Анаграммы в src/главная/котлин . Расширить Строка чтобы добавить функцию, которая возвращает строку с одинаковыми символами в лексикографическом порядке, добавьте следующий код в Anagrams.kt :

package com.okta.developer

fun String.sort(): List = this.toList().sorted()

Идиома Функции расширения предоставляет механизм расширения класса без использования наследования, позволяя писать новые функции для классов в сторонних библиотеках, которые нельзя изменить, даже если они являются конечными классами. В приведенном выше коде мы объявляем функцию sort() как расширение для класса String без параметров и возвращаемого типа List . sort() функция – это Функция с одним выражением , еще одна идиома Котлина для написания более короткого кода, так как ключевое слово return и заключающие скобки не требуются.

Под сортировкой() определите класс Анаграммы следующим образом:

class Anagrams {

    fun count(s: String): Int {
        var count = 0
        for (i in 1 until s.length) {
            var substrings = s.windowed(i, 1)
                .map { it.sort() }
                .toMutableList()
            while (substrings.isNotEmpty()) {
                val substring = substrings.removeAt(0)
                count += substrings.count{ it == substring }
            }
        }
        return count
    }
}

Цикл for в count(s: Строка) функция будет повторяться я в полуоткрытом диапазоне , из 1 до с.длина , не включая с.длина . Таким образом, на каждой итерации с использованием оконной функции Строка , мы создаем все возможные подстроки текущей длины i . Затем сортируйте() все подстроки и создайте Изменяемый список , чтобы иметь возможность удалять элементы позже. Каждый тип коллекции в стандартной библиотеке Kotlin (набор, список, карта) предоставляет только для чтения и изменяемый интерфейс, определяющий операции записи.

По мере сортировки подстрок их можно сравнивать друг с другом, чтобы найти анаграммы. Используя функцию List count() и передавая лямбда-предикат, выраженный параметром it , будет возвращено количество совпадений. Много раз лямбда-выражение имеет только один параметр и неявное имя одного параметра он допускает более короткий синтаксис.

Добавьте следующие тестовые примеры для класса Anagram в новый файл Kotlin src/test/kotlin/Anagrams Test.kt :

package com.okta.developers

import org.junit.Test
import kotlin.test.assertEquals

class AnagramsTest {

    val anagrams = Anagrams()

    @Test
    fun `given abba count returns 4`(){
        assertEquals(4, anagrams.count("abba"))
    }

    @Test
    fun `given ifailuhkqq count returns 3`(){
        assertEquals(3, anagrams.count("ifailuhkqq"))
    }
}

Запустите тестовые примеры с помощью Maven:

mvn test

Результаты теста отобразятся в консоли:

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.okta.developer.AnagramsTest
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.083 sec

Results :

Tests run: 2, Failures: 0, Errors: 0, Skipped: 0

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

[INFO] --- exec-maven-plugin:1.2.1:java (default) @ kotlin-hello-world ---
abba
4
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

Учебное Пособие: Используйте Kotlin С Пружинной Загрузкой Безопасно

Наконец, давайте посмотрим, насколько легко создать приложение для загрузки Kotlin Spring с аутентификацией Okta OpenID Connect (OIDC).

Используя API Spring Initializr/|, создайте проект Maven с помощью следующей команды:

curl https://start.spring.io/starter.zip -d dependencies=web,okta \
-d language=kotlin \
-d type=maven-project \
-d groupId=com.okta.developer \
-d artifactId=kotlin-spring-boot \
-d name="Kotlin Spring Boot" \
-d description="Demo project of a Kotlin Spring Boot application" \
-d packageName=com.okta.developer \
-o kotlin-spring-boot.zip

Распакуйте файл:

unzip kotlin-spring-boot.zip -d kotlin-spring-boot
cd kotlin-spring-boot

Защитите свое приложение с помощью OpenID Connect

Если у вас уже есть учетная запись Okta, см. раздел Создание веб-приложения на боковой панели Okta ниже. В противном случае мы создали плагин Maven, который настраивает бесплатную учетную запись разработчика Okta + приложение OIDC (менее чем за минуту!).

./mvnw com.okta:okta-maven-plugin:setup

Вы должны увидеть следующий вывод:

First name: Jimena
Last name: Garbarino
Email address: ***
Company: ***
Creating new Okta Organization, this may take a minute:
OrgUrl: https://dev-123456.okta.com
Check your email address to verify your account.

Writing Okta SDK config to: /home/indiepopart/.okta/okta.yaml

Configuring a new OIDC, almost done:
Created OIDC application, client-id: ***

Проверьте свою электронную почту и следуйте инструкциям, чтобы активировать свою учетную запись Okta.

Если у вас уже есть учетная запись разработчика Okta

Войдите в систему и создайте новое приложение:

  • На странице Приложения выберите Добавить приложение .
  • На странице Создать новое приложение , выберите Веб .
  • Дайте вашему приложению запоминающееся имя, добавьте http://localhost:8080/login/oauth2/code/okta в качестве URL-адреса перенаправления для входа в систему.

Скопируйте издателя (найденного в разделе API > Серверы авторизации ), идентификатор клиента и секрет клиента в src/основные/ресурсы/приложение.свойства .

okta.oauth2.issuer=$issuer
okta.oauth2.client-id=$clientId
okta.oauth2.client-secret=$clientSecret

Отредактируйте Загрузочное приложение Kotlin Spring , расположенное в пакете com.okta.developer , чтобы добавить сопоставление контроллера, которое будет выводить приветственное сообщение в окне браузера.

package com.okta.developer

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.security.core.annotation.AuthenticationPrincipal
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController

@SpringBootApplication
@RestController
class KotlinSpringBootApplication {

    @GetMapping("/")
    fun hello(@AuthenticationPrincipal authenticationToken: OAuth2AuthenticationToken): String {
        return "Welcome ${authenticationToken.principal.attributes["name"]}"
    }
}

fun main(args: Array) {
    runApplication(*args)
}

Как вы можете видеть, в функции hello() аутентифицированный пользователь передается в токене аутентификации . Аннотация @authenticationprincipal из Spring Security помогает преобразовать принципала в ожидаемый тип принципала. Приветственное сообщение построено с использованием Строковой интерполяции , идиомы Котлина для замены переменных внутри строк.

Запустите приложение с помощью следующей команды:

./mvnw spring-boot:run

Перейдите к http://localhost:8080 и приложение должно запустить поток кода аутентификации OAuth 2.0, перенаправляя на страницу входа в систему Okta.

После входа в систему вы должны увидеть приветственное сообщение:

Welcome, Jimena Garbarino

Теперь у вас есть безопасное приложение всего с несколькими строками Kotlin и помощью Spring Boot!

Узнайте больше о Kotlin, Java и безопасной аутентификации с помощью этих учебных пособий

Я надеюсь, что этот пост в блоге помог вам понять, насколько лаконичен и выразителен Котлин и почему разработчикам это нравится. Вы можете найти весь обучающий код в репозиториях котлин – привет-мир и котлин-пружинный ботинок на GitHub. Чтобы узнать больше о Kotlin, перейдите по следующим ссылкам:

Вопросы? Запросы на будущую должность? Оставляйте их в комментариях! И не забудь следовать @oktadev в Твиттере и подпишитесь на наш канал YouTube .

Оригинал: “https://dev.to/oktadev/kotlin-a-beginner-s-guide-and-tutorial-3f8l”