Шаг 243.
Основы Kotlin.
Совместимость с Java. Функциональные типы в Java

    На этом шаге мы рассмотрим использование функциональных типов.

    Функциональные типы и анонимные функции - это новаторское включение в язык программирования Kotlin, представляющее рациональный способ общения между компонентами. Их лаконичный синтаксис возможен благодаря оператору ->, но лямбды недоступны в версиях до Java 8.

    Как же выглядят эти функциональные типы при вызове из Java? Ответ может выглядеть обманчиво простым: в Java функциональные типы представлены интерфейсами с именами FunctionN, где N - количество принимаемых аргументов.

    Чтобы убедиться в этом, добавьте в Hero.kt функциональный тип с именем translator. Тип translator принимает строку, преобразует символы в строчные, первую букву делает прописной и выводит результат.

@file:JvmName("Hero")

fun main(args: Array<String>) {
    .   .   .   .
    adversary.offerFood()

    try {
        adversary.extendHandInFriendship()
    } catch (e: Exception) {
        println("Begone, foul beast!")
    }
}

val translator = { utterance: String ->
    println(utterance.toLowerCase().capitalize())
}

fun makeProclamation() = "Greetings, beast!"


Рис.1. Объявление функционального типа translator (Hero.kt)

    Тип translator определяется так же, как другие функциональные типы. Он имеет тип (String)->Unit. Чтобы увидеть, как этот тип будет выглядеть в Java, сохраните экземпляр translator в переменную в Jhava.

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class Jhava {

    private int hitPoints = 52489112;
    private String greeting = "BLARGH";

    public static void main(String[] args) {
        .   .   .   .
        System.out.println("Max spell count: " + Spellbook.MAX_SPELL_COUNT);

        Spellbook.getSpellbookGreeting();

        Function1<String, Unit> translator = Hero.getTranslator();
    }

    @NotNull
    public String utterGreeting() {
        return greeting;
    }
.   .   .   .   .
}


Рис.2. Сохранение функционального типа в Java-переменной (Jhava.java)


Вам понадобится импортировать тип Kotlin.Unit; убедитесь, что выбрали версию из стандартной библиотеки Kotlin. Также вам понадобится импортировать kotlin.jvm.functions.Function1.

    Этот функциональный тип имеет тип Function1<String, Unit>;. Function1 - это базовый тип, потому что translator имеет ровно один параметр. String и Unit используются как параметры типов потому, что translator принимает параметр типа String и возвращает Kotlin-тип Unit.

    Существуют 23 интерфейса Function, начиная с Function0 и заканчивая Function22. Каждый из них содержит одну функцию - invoke. invoke служит для вызова функционального типа, поэтому каждый раз, когда вам необходимо вызвать функциональный тип, вы используете для этого invoke. Вызовите translator в Jhava.

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class Jhava {

    private int hitPoints = 52489112;
    private String greeting = "BLARGH";

    public static void main(String[] args) {
        .   .   .   .
        System.out.println("Max spell count: " + Spellbook.MAX_SPELL_COUNT);

        Spellbook.getSpellbookGreeting();

        Function1<String, Unit> translator = Hero.getTranslator();
        translator.invoke("TRUCE");
    }

    @NotNull
    public String utterGreeting() {
        return greeting;
    }
.   .   .   .   .
}
Файл с проектом можно взять здесь.


Рис.3. Вызов функционального типа в Java (Jhava.java)

    Запустите Jhava.kt и убедитесь, что Truce выводится в консоль.


Рис.4. Результат работы приложения

    Функциональные типы полезны в Kotlin, но помните, как они представлены в Java. Лаконичный, текучий синтаксис Kotlin, который вы наверняка полюбили, превращается в громоздкую конструкцию в Java. Если ваш код доступен для классов Java, например, как часть API, тогда лучше отказаться от функциональных типов. Но если вас устраивает более многословный синтаксис, то просто знайте, что функциональные типы Kotlin доступны в Java.

    Совместимость Java и Kotlin является прочной основой роста Kotlin. Она дает возможность использовать из Kotlin существующие фреймворки, такие как Android, и взаимодействовать со старым кодом на Java, что позволит вам постепенно внедрить Kotlin в своих проектах. К счастью, организация взаимодействий между Kotlin и Java не вызывает затруднений, за несколькими исключениями. Умение писать код на Kotlin, дружелюбный для Java, и наоборот - полезный навык, который окупится при дальнейшем изучении Kotlin.

    В следующих шагах вы создадите ваше первое приложение для Android на Kotlin, которое сгенерирует стартовые параметры для игроков в NyetHack.

    Со следующего шага мы начнем рассматривать создание Android-приложений на Kotlin.




Предыдущий шаг Содержание Следующий шаг