Привет, Хаброжители!
Kotlin — это язык программирования со статической типизацией, который взяла на вооружение Google в ОС Android. Кроме того, это мультиплатформенный язык, позволяющий создавать приложения для macOS, Windows и iOS.
Джош Скин, Дэвид Гринхол, Эндрю Бэйли на практических примерах познакомят вас с ключевыми концепциями Kotlin и фундаментальными API.
Вы начнете с основных принципов и перейдете к расширенному использованию нетривиальных возможностей Kotlin, чтобы создавать надежные и эффективные приложения, а так же освоите среду разработки IntelliJ IDEA от JetBrains.
Лямбда-выражения и стандартная библиотека Kotlin
Итак, теперь вы знаете основы объявления и вызова функций, использующих лямбда-выражения. Давайте подробнее рассмотрим стандартную библиотеку Kotlin, чтобы понять, как лямбда-выражения применяются в языке. Включите в функцию main вызов функции require, которая была впервые представлена в главе 7.
Листинг 8.16. Возвращение к require (NyetHack.kt)
Как вы уже догадались, фигурные скобки после вызова require определяют лямбда-выражение. Этому конкретному лямбда-выражению присвоено имя lazyMessage и тип () -> Any.
require проверяет условие, переданное в первом аргументе. Если условие ложно, выдается исключение IllegalArgumentException с сообщением, сгенерированным лямбда-выражением. (Кстати говоря, лямбда-выражение lazyMessage не является обязательным. Если значение не передается, по умолчанию используется пустая строка.) В данном случае лямбда-выражение применяется для оптимизации: строка вычисляется только в том случае, если она необходима для выдачи исключения.
Функциональность lazyMessage не уникальна для require. Собственно, она доступна почти для всех предусловий, о которых мы говорили в главе 7, включая requireNotNull, check, checkNotNull и assert. (Функция error занимает особое место: это единственная функция проверки предусловий, не имеющая ленивого сообщения. Вместо этого она получает сообщение в String.)
В добавление к оптимизации производительности в стандартной библиотеке Kotlin есть ряд функций, позволяющих выражать сложные алгоритмы в одной строке кода.
Допустим, вы хотите присвоить игроку титул, зависящий от его имени, например «Повелитель гласных» (The Master of Vowels), если имя содержит много гласных, или «Узнаваемый» (Identifiable), если имя состоит из цифр. Тип String в Kotlin включает несколько функций с лямбда-аргументами, которые могут пригодиться для принятия подобных решений.
Добавьте в main функцию createTitle. Сначала проверьте, содержит ли имя игрока более четырех гласных, и если содержит, назначьте ему титул The Master of Vowels.
Листинг 8.17. Определение createTitle (NyetHack.kt)
Запустите NyetHack и введите имя с большим количеством гласных, например Aurelia. Результат должен выглядеть примерно так (в зависимости от текущего настроения рассказчика):
Другая полезная строковая функция — all — проверяет, что каждый символ строки удовлетворяет заданному предикату (вроде (Char) -> Boolean). Также существует функция none, которая проверяет обратное условие — что ни один символ строки не удовлетворяет заданному предикату.
Определим еще два титула для игрока. Если имя игрока состоит только из цифр, ему должен быть присвоен титул The Identifiable (Узнаваемый), а если оно не содержит ни одной буквы — титул The Witness Protection Member (Участник программы по защите свидетелей). Конечно, цифры тоже не являются буквами, поэтому в выражении when необходимо тщательно упорядочить условия, чтобы все титулы назначались по задуманным вами правилам.
Листинг 8.18. Добавление титулов (NyetHack.kt)
Протестируйте свой код с входными данными 11, **** и т.д., чтобы убедиться в том, что игрокам присваиваются правильные титулы.
Функции all, none и count позволяют компактно выполнять такие проверки. Без этих функций разработчику пришлось бы самостоятельно реализовать эти классы (вероятно, для этого потребуется 5–10 строк кода на каждое условие).
Стандартная библиотека Kotlin включает множество функций, которые делают ваш код более компактным и понятным. Вы больше узнаете об этих функциях и получите некоторое представление о способах функционального программирования в главе 11.
Для любознательных: ссылки на функции
До сих пор вы объявляли лямбда-выражения для передачи функции в виде аргумента другой функции. Сделать это можно иначе: передать ссылку на функцию. Ссылка на функцию преобразует обычную функцию, определенную с ключевым словом fun, в значение с типом функции. Ссылку на функцию можно использовать везде, где допускается лямбда-выражение.
Допустим, вы хотите выделить из кода лямбда-выражение, выводящее текст желтым цветом. Для этого реализация лямбда-выражения извлекается в отдельную функцию и применяется синтаксис ссылки на функцию (выделен в примере кода ниже):
Чтобы получить ссылку на функцию, примените оператор :: к имени этой функции. Ссылки на функции могут пригодиться во многих ситуациях. Если у вас есть именованная функция, соответствующая требованиям к параметру, который должен получать аргумент-функцию, ссылка на функцию позволит использовать ее вместо определения лямбда-выражения. А может быть, вы захотите передать в аргументе функцию из стандартной библиотеки Kotlin. Ссылки на функции позволяют решать такие задачи еще компактнее, чем лямбда-выражения.
Для любознательных: захват лямбда-выражений
В языке Kotlin лямбда-функция может изменять переменные и ссылаться на них вне своей области видимости. Лямбда-функция захватывает переменные, объявленные за ее пределами, то есть сохраняет ссылки на эти переменные, как было показано на примере первого лямбда-выражения в функции narrate.
Для демонстрации такого свойства лямбда-функций давайте добавим еще одно настроение рассказчика в функцию changeNarratorMood:
Листинг 8.19. Изменение переменных из лямбда-функции (Narrator.kt)
Новая переменная настроения учитывает количество вариантов повествования. Прежде чем выполнять код, ненадолго остановитесь и спросите себя: что будет делать этот код? Чтобы подтвердить свои догадки, запустите NyetHack (возможно, программу придется пару раз перезапустить, чтобы добраться до нового настроения рассказчика). Результат будет выглядеть примерно так:
Ваша догадка подтвердилась? Разберемся, что здесь происходит.
Хотя переменная narrationsGiven определяется за пределами лямбда-функции, последняя может обращаться к переменной и изменять ее. Таким образом, значение narrationsGiven увеличивается с 0 до 1 и с 1 до 2.
Задание: новые титулы и настроения
NyetHack в настоящее время поддерживает пять вариантов настроения и четыре титула, которые могут назначаться игроку, но полету фантазии нет предела. Проявите творческий подход и добавьте любые новые варианты настроения и титулы на свое усмотрение.
Вот несколько возможных идей для настроения.
• Ленивое: рассказчик выдает только первую часть выводимого сообщения. (Подсказка: воспользуйтесь функциями take или substring типа String.)
• Таинственное: рассказчик использует шифр leet, заменяя буквы похожими цифрами или знаками. Например, L заменяем на 1; E — на 3; T — на 7. (Подсказка: присмотритесь к функции replace типа String. Есть версия функции replace, которая получает во втором параметре лямбда-функцию.)
• Поэтическое: рассказчик делает между словами паузы (вставляем разрывы строк), чтобы придать тексту поэтический стиль. К сожалению, из-за сложности языка и размера у рассказчика вряд ли получится шедевр. (Подсказка: возможных решений много, но как вариант можно объединить функцию replace с классом Random, который мы уже использовали ранее в этой главе.)
А вот несколько идей для титулов, которые можно назначать игрокам.
• «Выдающийся»: назначается игроку, если все буквы в его имени записаны в верхнем регистре.
• «Пространный»: назначается игроку, если в его имени слишком много букв (пороговое значение для «слишком много» выберите сами).
• «Носитель палиндрома»: назначается игроку, если его имя является палиндромом. (Подсказка: обратите внимание на функцию reverse класса String. Не забудьте, что в строках учитывается регистр символов.)
Более подробно с книгой можно ознакомиться на сайте издательства
» Оглавление
» Отрывок
По факту оплаты бумажной версии книги на e-mail высылается электронная книга.
Для Хаброжителей скидка 25% по купону — Kotlin