Волшебство Kotlin Пьер-Ив Симон Язык программирования должен быть вы- Волшебство «Потрясающее введение во разительным, безопасным, гибким и интуи- вселенную функционального тивно понятным. Kotlin соответствует всем программирования». этим требованиям! Этот элегантный язык для Алексей Слайковский, Oracle В JVM легко интегрируется с Java и позволяет «Отличные, простые и понятные легко переключаться между объектно-ори- Kotlin примеры функционального про- ентированным и функциональным стилями о граммирования на Kotlin». программирования. Также он поддерживается Эммануэль Медина, Global HITSS компанией Google как один из основных язы- л ков программирования для Android. Овладев «Прекрасный справочник для ш приемами, которые описываются в книге, вы тех, кто хочет изучать Kotlin или функциональное программиро- сможете решать новые задачи уверенно и эф- вание, но не знает, с чего начать. фективно. Описывает сложные задачи, ко- е Эта книга научит вас писать на Kotlin выра- торые часто недооцениваются, и зительные, безопасные и простые в обслужи- объясняет их решение». б вании программы. Опытный инженер Пьер- Бриджер Хоуэлл, SoFi Ив Сомон научит вас подходить к решению с «Объединяя Kotlin и функцио- общих задач с позиций функционального нальное программирование, эта программирования. На множестве практи- книга представляет только те те- т ческих примеров вы увидите, как правильно оретические выкладки, которые обрабатывать ошибки и данные, управлять в вам действительно пригодятся, состоянием и использовать отложенные вы- и иллюстрирует их множеством числения. Наглядные примеры и практиче- практических примеров». о ские идеи автора помогут вам стать успешным Жан-Франсуа Морен, разработчиком! Университет Лаваля K В книге рассматриваются: • программирование с использованием функций; o • обработка необязательных данных; • безопасная обработка ошибок и исключений; t • совместное использование изменяемого состояния. l Пьер-Ив Симон – программист, инженер-исследователь в Alcatel i Submarine Networks. Автор книги Functional Programming in Java. n ISBN 978-5-97060-801-2 Издание адресовано разработчикам, использующим Java и Kotlin.. Интернет-магазин: www.dmkpress.com Оптовая продажа: КТК “Галактика” [email protected] www.дмк.рф 9 785970 608012 1 / 54 Пьер-Ив Сомон Волшебство Kotlin 2 / 54 The Joy of Kotlin PIERRE-YVES SAUMONT 3 / 54 Волшебство Kotlin ПЬЕР-ИВ СОМОН Москва, 2020 4 / 54 УДК 004.43Kotlin ББК 32.972 С61 Сомон. П.-И. С61 Волшебство Kotlin / пер. с англ. А. Н. Киселева. – М.: ДМК Пресс, 2020. – 536 с.: ил. ISBN 978-5-97060-801-2 Kotlin – один из самых новых языков в экосистеме Java, устраняющий многие ограничения Java и гораздо более универсальный. Среди его преимуществ: полная совместимость с Java и возможность интеграции на уровне исходного кода, широкая поддержка парадигмы функционального программирования, помогающая писать надежный и безопасный код, лаконичность синтаксиса, а также, что весьма немало- важно, гарантии поддержки со стороны IT-гиганта Google. Пьер-Ив Сомон, опытный разработчик на Java, в своей книге подробно освещает нюансы программирования на Kotlin, переходя от общего описания языка к его характерным особенностям и возможностям, включая приемы функционального программирования. Издание предназначено для разработчиков, знакомых с Java и стремящихся повы- сить безопасность своих программ, а также упростить их написание, тестирование и сопровождение. УДК 004.43Kotlin ББК 32.972 Original English language edition published by Manning Publications USA, USA. Copyright © 2018 by Manning Publications Co. Russian-language edition copyright © 2020 by DMK Press. All rights reserved. Все права защищены. Любая часть этой книги не может быть воспроизведена в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения вла- дельцев авторских прав. ISBN 978-1-617-29536-2 (англ.) Copyright © 2018 by Manning Publications Co. ISBN 978-5-97060-801-2 (рус.) © Оформление, издание, перевод, ДМК Пресс, 2020 5 / 54 Оглавление 1 Создание безопасных программ ...........................................................31 2 Функциональное программирование на Kotlin: обзор ........................46 3 Программирование с функциями .........................................................81 4 Рекурсия, сорекурсия и мемоизация ..................................................120 5 Обработка данных с использованием списков ..................................161 6 Необязательные данные ......................................................................197 7 Обработка ошибок и исключений .......................................................222 8 Дополнительные операции со списками ............................................248 9 Ленивые вычисления ...........................................................................282 10 Обработка данных с использованием деревьев .................................323 11 Решение задач с использованием усовершенствованных деревьев ...363 12 Функциональный ввод/вывод .............................................................392 13 Общее изменяемое состояние и акторы .............................................420 14 Решение типичных проблем функциональным способом ................448 6 / 54 Содержание Оглавление .....................................................................................................5 Предисловие .................................................................................................15 Благодарности ............................................................................................19 О книге .........................................................................................................20 Об авторе ....................................................................................................28 Об иллюстрации на обложке .......................................................................29 1 Создание безопасных программ ..............................................31 1.1 Программные ловушки ................................................................33 1.1.1 Безопасная обработка эффектов ..........................................35 1.1.2 Увеличение безопасности программ за счет ссылочной прозрачности .........................................................................36 1.2 Выгоды безопасного программирования ................................37 1.2.1 Использование подстановочной модели в рассуждениях о программе ............................................................................39 1.2.2 Применение принципов соблюдения безопасности на простом примере ..............................................................40 1.2.3 Максимальное использование абстракций ............................44 Итоги ..........................................................................................................45 2 Функциональное программирование на Kotlin: обзор .........................................................................................................46 2.1 Поля и переменные в Kotlin ........................................................47 2.1.1 Тип можно опустить для простоты .....................................47 2.1.2 Изменяемые поля ...................................................................47 2.1.3 Отложенная инициализация .................................................48 2.2 Классы и интерфейсы в Kotlin ....................................................49 2.2.1 Еще большее сокращение кода ...............................................51 2.2.2 Реализация интерфейса или расширение класса ..................51 7 / 54 Содержание 7 2.2.3 Создание экземпляра класса ..................................................52 2.2.4 Перегрузка конструкторов ....................................................52 2.2.5 Создание методов equals и hashCode .....................................53 2.2.6 Деструктуризация объектов данных ....................................55 2.2.7 Реализация статических членов в Kotlin ...............................55 2.2.8 Синглтоны .............................................................................56 2.2.9 Предотвращение создания экземпляров служебных классов ....................................................................................56 2.3 В Kotlin нет элементарных типов ..............................................57 2.4 Два типа коллекций в Kotlin .......................................................57 2.5 Пакеты в Kotlin ...............................................................................59 2.6 Видимость в Kotlin .......................................................................60 2.7 Функции в Kotlin ............................................................................61 2.7.1 Объявление функций ...............................................................61 2.7.2 Локальные функции ................................................................62 2.7.3 Переопределение функций ......................................................63 2.7.4 Функции-расширения .............................................................63 2.7.5 Лямбда-выражения ................................................................64 2.8 Пустое значение null в Kotlin ......................................................66 2.8.1 Приемы работы с типами, поддерживающими null .............66 2.8.2 Оператор Элвис и значение по умолчанию ............................67 2.9 Поток выполнения программы и управляющие структуры ........................................................................................67 2.9.1 Условная конструкция ...........................................................68 2.9.2 Использование конструкций с несколькими условиями .........69 2.9.3 Циклы .....................................................................................70 2.9.4 Какие проблемы может вызывать поддержка вариантности? ......................................................................76 2.9.5 Когда использовать объявления ковариантности и контрвариантности ..........................................................77 2.9.6 Объявление вариантности в точке определения и точке использования ...........................................................78 Итоги ..........................................................................................................79 3 Программирование с функциями ...........................................81 3.1 Что такое функция? ......................................................................82 3.1.1 Отношения между двумя областями функций .....................83 3.1.2 Обратные функции в Kotlin ...................................................84 3.1.3 Частичные функции ...............................................................85 3.1.4 Композиция функций ..............................................................86 3.1.5 Функции нескольких аргументов ...........................................86 3.1.6 Каррирование функций ..........................................................87 3.1.7 Частично-примененные функции ..........................................87 3.1.8 Функции не имеют эффектов ................................................88 3.2 Функции в Kotlin ............................................................................89 8 / 54 8 Содержание 3.2.1 Функции как данные ...............................................................89 3.2.2 Данные как функции ...............................................................89 3.2.3 Конструкторы объектов как функции ..................................89 3.2.4 Использование функций fun в Kotlin .......................................90 3.2.5 Объектная и функциональная нотация ................................93 3.2.6 Использование функций как значений ...................................94 3.2.7 Ссылки на функции .................................................................96 3.2.8 Композиция функций fun ........................................................97 3.2.9 Повторное использование функций .......................................98 3.3 Дополнительные особенности функций ..................................99 3.3.1 Функции с несколькими аргументами? .................................99 3.3.2 Применение каррированных функций ..................................100 3.3.3 Реализация функций высшего порядка .................................100 3.3.4 Полиморфные функции высшего порядка ............................102 3.3.5 Анонимные функции .............................................................104 3.3.6 Локальные функции ..............................................................106 3.3.7 Замыкания ............................................................................106 3.3.8 Частичное применение функций и автоматическое каррирование .......................................................................107 3.3.9 Перестановка аргументов частично примененных функций ................................................................................112 Итоги ........................................................................................................119 4 Рекурсия, сорекурсия и мемоизация ...................................120 4.1 Рекурсия и сорекурсия ...............................................................121 4.1.1 Реализация сорекурсии .........................................................121 4.1.2 Реализация рекурсии ............................................................123 4.1.3 Различия между рекурсивными и сорекурсивными функциями ............................................................................124 4.1.4 Выбор между рекурсией и сорекурсией .................................125 4.2 Удаление хвостового вызова ....................................................127 4.2.1 Использование механизма удаления хвостового вызова .....128 4.2.2 Преобразование циклов в хвостовую рекурсию ...................128 4.2.3 Рекурсивные функции-значения ...........................................132 4.3 Рекурсивные функции и списки ..............................................135 4.3.1 Дважды рекурсивные функции .............................................137 4.3.2 Абстракция рекурсии в списках ...........................................140 4.3.3 Обращение списка ................................................................143 4.3.4 Сорекурсивные списки ..........................................................145 4.3.5 Опасность строгости..........................................................149 4.4 Мемоизация .................................................................................149 4.4.1 Мемоизация в программировании на основе циклов ...........149 4.4.2 Мемоизация рекурсивных функций ......................................150 4.4.3 Неявная мемоизация ............................................................152 4.4.4 Автоматическая мемоизация .............................................154 4.4.5 Мемоизация функций нескольких аргументов ....................157 9 / 54 Содержание 9 4.5 Являются ли мемоизованные функции чистыми? ..............159 Итоги ........................................................................................................159 5 Обработка данных с использованием списков .............161 5.1 Классификация коллекций данных ........................................162 5.2 Разные типы списков .................................................................162 5.3 Производительность списков ...................................................164 5.3.1 Время в обмен на объем памяти и сложность ....................165 5.3.2 Отказ от изменения на месте ............................................165 5.4 Какие виды списков доступны в Kotlin? ................................167 5.4.1 Использование постоянных структур данных ....................168 5.4.2 Реализация неизменяемого, постоянного, односвязного списка ........................................................................168 5.5 Совместное использование данных в операциях со списками ..................................................................................172 5.6 Дополнительные операции со списками ...............................174 5.6.1 Преимущества объектной нотации ....................................175 5.6.2 Объединение списков ............................................................178 5.6.3 Удаление элементов с конца списка ....................................180 5.6.4 Использование рекурсии для свертки списков с помощью функций высшего порядка ..................................181 5.6.5 Вариантность .....................................................................182 5.6.6 Безопасная рекурсивная версия foldRight .............................191 5.6.7 Отображение и фильтрация списков ..................................193 Итоги ........................................................................................................196 6 Необязательные данные ............................................................197 6.1 Проблемы с пустым указателем ..............................................198 6.2 Как пустые ссылки обрабатываются в Kotlin ........................201 6.3 Альтернативы пустым ссылкам ...............................................202 6.4 Тип Option .....................................................................................205 6.4.1 Извлечение значения из Option ............................................207 6.4.2 Применение функций к необязательным значениям ...........209 6.4.3 Композиция функций с типом Option ..................................210 6.4.4 Примеры использования Option ...........................................212 6.4.5 Другие способы комбинирования типа Options ...................215 6.4.6 Комбинирование List и Option ..............................................218 6.4.7 Когда и как использовать тип Option .................................220 Итоги ........................................................................................................221 7 Обработка ошибок и исключений ........................................222 7.1 Проблемы с отсутствующими данными ................................223 7.2 Тип Either ......................................................................................224 7.3 Тип Result ......................................................................................227 10 / 54