«Scala. Профессиональное программирование» — главная книга по Scala, популярному языку для платформы Java, в котором сочетаются концепции объектно-ориентированного и функционального программирования, благодаря чему он превращается в уникальное и мощное средство разработки.
Этот авторитетный труд, написанный создателями Scala, поможет вам пошагово изучить язык и идеи, лежащие в его основе.
Данное четвертое издание полностью обновлено. Добавлен материал об изменениях, появившихся в Scala 2.13, в том числе:
• новая иерархия типов коллекций;
• новые конкретные типы коллекций;
• новые методы, добавленные к коллекциям;
• новые способы определять собственные типы коллекций;
• новые упрощенные представления.
Author(s): Мартин Одерски, Лекс Спун, Билл Веннерс
Series: Библиотека программиста
Edition: 4
Publisher: Питер
Year: 2021
Language: Russian
Commentary: Vector PDF
Pages: 720
City: СПб.
Tags: Programming; Multithreading; GUI; Java; Functional Programming; Scala; Object-Oriented Programming; Syntactic Analysis; Closures; Testing; XML; Metaprogramming
Предисловие
Благодарности
Введение
Целевая аудитория
Как пользоваться книгой
Как изучать Scala
Условные обозначения
Обзор глав
Ресурсы
Исходный код
От издательства
Глава 1. Масштабируемый язык
1.1. Язык который растет вместе с вами
Растут новые типы
Растут новые управляющие конструкции
1.2. Что делает Scala масштабируемым языком
Scala — объектно-ориентированный язык
Scala — функциональный язык
1.3. Почему именно Scala
Scala — совместимый язык
Scala — лаконичный язык
Scala — язык высокого уровня
Scala — статически типизированный язык
1.4. Истоки Scala
Резюме
Глава 2. Первые шаги в Scala
2.1. Шаг 1. Осваиваем интерпретатор Scala
2.2. Шаг 2. Объявляем переменные
2.3. Шаг 3. Определяем функции
2.4. Шаг 4. Пишем Scala-скрипты
2.5. Шаг 5. Организуем цикл с while и принимаем решение с if
2.6. Шаг 6. Перебираем элементы с foreach и for
Резюме
Глава 3. Дальнейшие шаги в Scala
3.1. Шаг 7. Параметризуем массивы типами
3.2. Шаг 8. Используем списки
3.3. Шаг 9. Используем кортежи
3.4. Шаг 10. Используем множества и отображения
3.5. Шаг 11. Учимся распознавать функциональный стиль
3.6. Шаг 12. Читаем строки из файла
Резюме
Глава 4. Классы и объекты
4.1. Классы поля и методы
4.2. Когда подразумевается использование точки с запятой
4.3. Объекты-одиночки
4.4. Приложение на языке Scala
4.5. Трейт App
Резюме
Глава 5. Основные типы и операции
5.1. Некоторые основные типы
5.2. Литералы
Целочисленные литералы
Литералы чисел с плавающей точкой
Символьные литералы
Строковые литералы
Литералы обозначений
Булевы литералы
5.3. Интерполяция строк
5.4. Все операторы являются методами
5.5. Арифметические операции
5.6. Отношения и логические операции
5.7. Поразрядные операции
5.8. Равенство объектов
5.9. Приоритет и ассоциативность операторов
5.10. Обогащающие оболочки
Резюме
Глава 6. Функциональные объекты
6.1. Спецификация класса Rational
6.2. Конструирование класса Rational
6.3. Переопределение метода toString
6.4. Проверка соблюдения предварительных условий
6.5. Добавление полей
6.6. Собственные ссылки
6.7. Вспомогательные конструкторы
6.8. Приватные поля и методы
6.9. Определение операторов
6.10. Идентификаторы в Scala
6.11. Перегрузка методов
6.12. Неявные преобразования
6.13. Предостережение
Резюме
Глава 7. Встроенные управляющие конструкции
7.1. Выражения if
7.2. Циклы while
7.3. Выражения for
Обход элементов коллекций
Фильтрация
Вложенные итерации
Привязки промежуточных переменных
Создание новой коллекции
7.4. Обработка исключений с помощью выражений try
Генерация исключений
Перехват исключений
Условие finally
Выдача значения
7.5. Выражения match
7.6. Программирование без break и continue
7.7. Область видимости переменных
7.8. Рефакторинг кода написанного в императивном стиле
Резюме
Глава 8. Функции и замыкания
8.1. Методы
8.2. Локальные функции
8.3. Функции первого класса
8.4. Краткие формы функциональных литералов
8.5. Синтаксис заместителя
8.6. Частично примененные функции
8.7. Замыкания
8.8. Специальные формы вызова функций
Повторяющиеся параметры
Именованные аргументы
Значения параметров по умолчанию
8.9. Хвостовая рекурсия
Трассировка функций с хвостовой рекурсией
Ограничения хвостовой рекурсии
Резюме
Глава 9. Управляющие абстракции
9.1. Сокращение повторяемости кода
9.2. Упрощение клиентского кода
9.3. Карринг
9.4. Создание новых управляющих конструкций
9.5. Передача параметров по имени
Резюме
Глава 10. Композиция и наследование
10.1. Библиотека двумерной разметки
10.2. Абстрактные классы
10.3. Определяем методы без параметров
10.4. Расширяем классы
10.5. Переопределяем методы и поля
10.6. Определяем параметрические поля
10.7. Вызываем конструктор суперкласса
10.8. Используем модификатор override
10.9. Полиморфизм и динамическое связывание
10.10. Объявляем финальные элементы
10.11. Используем композицию и наследование
10.12. Реализуем методы above beside и toString
10.13. Определяем фабричный объект
10.14. Методы heighten и widen
10.15. Собираем все воедино
Резюме
Глава 11. Иерархия Scala
11.1. Иерархия классов Scala
11.2. Как реализованы примитивы
11.3. Низшие типы
11.4. Определение собственных классов значений
Уход от монокультурности типов
Резюме
Глава 12. Трейты
12.1. Как работают трейты
12.2. Сравнение «тонких» и «толстых» интерфейсов
12.3. Пример: прямоугольные объекты
12.4. Трейт Ordered
12.5. Трейты как наращиваемые модификации
12.6. Почему не используется множественное наследование
12.7. Так все же с трейтами или без?
Резюме
Глава 13. Пакеты и импорты
13.1. Помещение кода в пакеты
13.2. Краткая форма доступа к родственному коду
13.3. Импортирование кода
13.4. Неявное импортирование
13.5. Модификаторы доступа
Приватные члены
Защищенные члены
Публичные члены
Область защиты
Видимость и объекты-компаньоны
13.6. Объекты пакетов
Резюме
Глава 14. Утверждения и тесты
14.1. Утверждения
14.2. Тестирование в Scala
14.3. Информативные отчеты об ошибках
14.4. Использование тестов в качестве спецификаций
14.5. Тестирование на основе свойств
14.6. Подготовка и проведение тестов
Резюме
Глава 15. Case-классы и сопоставление с образцом
15.1. Простой пример
Case-классы
Сопоставление с образцом
Сравнение match со switch
15.2. Разновидности паттернов
Подстановочные паттерны
Паттерны-константы
Патерны-переменные
Паттерны-конструкторы
Паттерны-последовательности
Паттерны-кортежи
Типизированные паттерны
Привязка переменной
15.3. Ограждение образца
15.4. Наложение паттернов
15.5. Запечатанные классы
15.6. Тип Option
15.7. Паттерны везде
Паттерны в определениях переменных
Последовательности вариантов в качестве частично примененных функций
Паттерны в выражениях for
15.8. Большой пример
Резюме
Глава 16. Работа со списками
16.1. Литералы списков
16.2. Тип List
16.3. Создание списков
16.4. Основные операции над списками
16.5. Паттерны-списки
16.6. Методы первого порядка класса List
Конкатенация двух списков
Принцип «разделяй и властвуй»
Получение длины списка: length
Обращение к концу списка: init и last
Реверсирование списков: reverse
Префиксы и суффиксы: drop take и splitAt
Выбор элемента: apply и indices
Линеаризация списка списков: flatten
Объединение в пары: zip и unzip
Отображение списков: toString и mkString
Преобразование списков: iterator toArray copyToArray
Пример: сортировка слиянием
16.7. Методы высшего порядка класса List
Отображения списков: map flatMap и foreach
Фильтрация списков: filter partition find takeWhile dropWhile и span
Применение предикатов к спискам: forall и exists
Свертка списков: foldLeft и foldRight
Пример: реверсирование списков с помощью свертки
Сортировка списков: sortWith
16.8. Методы объекта List
Создание списков из их элементов: List.apply
Создание диапазона чисел: List.range
Создание единообразных списков: List.fill
Табулирование функции: List.tabulate
Конкатенация нескольких списков: List.concat
16.9. Совместная обработка нескольких списков
16.10. Осмысление имеющегося в Scala алгоритма вывода типов
Резюме
Глава 17. Работа с другими коллекциями
17.1. Последовательности
Списки
Массивы
Буферы списков
Буферы массивов
Строки (реализуемые через StringOps)
17.2. Множества и отображения
Использование множеств
Применение отображений
Множества и отображения используемые по умолчанию
Отсортированные множества и отображения
17.3. Выбор между изменяемыми и неизменяемыми коллекциями
17.4. Инициализация коллекций
Преобразование в массив или список
Преобразования между изменяемыми и неизменяемыми множествами и отображениями
17.5. Кортежи
Резюме
Глава 18. Изменяемые объекты
18.1. Что делает объект изменяемым
18.2. Переназначаемые переменные и свойства
18.3. Практический пример: моделирование дискретных событий
18.4. Язык для цифровых схем
18.5. API моделирования
18.6. Моделирование электронной логической схемы
Класс Wire
Метод inverter
Методы andGate и orGate
Вывод симуляции
Запуск симулятора
Резюме
Глава 19. Параметризация типов
19.1. Функциональные очереди
19.2. Скрытие информации
Приватные конструкторы и фабричные методы
Альтернативный вариант: приватные классы
19.3. Аннотации вариантности
Вариантность и массивы
19.4. Проверка аннотаций вариантности
19.5. Нижние ограничители
19.6. Контравариантность
19.7. Приватные данные объекта
19.8. Верхние ограничители
Резюме
Глава 20. Абстрактные члены
20.1. Краткий обзор абстрактных членов
20.2. Члены-типы
20.3. Абстрактные val-переменные
20.4. Абстрактные var-переменные
20.5. Инициализация абстрактных val-переменных
Предынициализируемые поля
Ленивые val-переменные
20.6. Абстрактные типы
20.7. Типы зависящие от пути
20.8. Уточняющие типы
20.9. Перечисления
20.10. Практический пример: работа с валютой
Резюме
Глава 21. Неявные преобразования и параметры
21.1. Неявные преобразования
21.2. Правила для неявных преобразований
Названия неявных преобразований
Где применяются неявные преобразования
21.3. Неявное преобразование в ожидаемый тип
21.4. Преобразование получателя
Взаимодействие с новыми типами
Имитация нового синтаксиса
Неявные классы
21.5. Неявные параметры
Правило стиля для неявных параметров
21.6. Контекстные ограничители
21.7. Когда применяются множественные преобразования
21.8. Отладка неявных преобразований
Резюме
Глава 22. Реализация списков
22.1. Принципиальный взгляд на класс List
Объект Nil
Класс ::
Еще несколько методов
Создание списка
22.2. Класс ListBuffer
22.3. Класс List на практике
22.4. Внешняя функциональность
Резюме
Глава 23. Возвращение к выражениям for
23.1. Выражения for
23.2. Задача N ферзей
23.3. Выполнение запросов с помощью выражений for
23.4. Трансляция выражений for
Трансляция выражений for с одним генератором
Трансляция выражений for начинающихся с генератора и фильтра
Трансляция выражений for начинающихся с двух генераторов
Трансляция паттернов в генераторах
Трансляция определений
Трансляция применяемая для циклов
23.5. «Мы пойдем другим путем»
23.6. Обобщение for
Резюме
Глава 24. Углубленное изучение коллекций
24.1. Изменяемые и неизменяемые коллекции
24.2. Согласованность коллекций
24.3. Трейт Iterable
Подкатегории Iterable
24.4. Трейты последовательностей Seq IndexedSeq и LinearSeq
Буферы
24.5. Множества
24.6. Отображения
24.7. Конкретные классы неизменяемых коллекций
Списки
Ленивые списки
Неизменяемые ArraySeq
Векторы
Неизменяемые очереди
Диапазоны
Сжатые коллекции HAMT
Красно-черные деревья
Неизменяемые битовые множества
Векторные отображения
Списочные отображения
24.8. Конкретные классы изменяемых коллекций
Буферы массивов
Буферы списков
Построители строк
ArrayDeque
Очереди
Стеки
Изменяемые ArraySeq
Хеш-таблицы
Слабые хеш-отображения
Совместно используемые отображения
Изменяемые битовые множества
24.9. Массивы
24.10. Строки
24.11. Характеристики производительности
24.12. Равенство
24.13. Представления
24.14. Итераторы
Буферизованные итераторы
24.15. Создание коллекций с нуля
24.16. Преобразования между коллекциями Java и Scala
Резюме
Глава 25. Архитектура коллекций Scala
25.1. Исключение общих операций
Абстрагирование типов коллекций
Управление строгостью
Когда строгое вычисление предпочтительно или неизбежно
25.2. Интеграция новых коллекций
Ограниченные последовательности
Последовательности РНК
Префиксные отображения
Краткие выводы
Резюме
Глава 26. Экстракторы
26.1. Пример извлечения адресов электронной почты
26.2. Экстракторы
26.3. Паттерны без переменных или с одной переменной
26.4. Экстракторы переменного количества аргументов
26.5. Экстракторы и паттерны последовательностей
26.6. Сравнение экстракторов и case-классов
26.7. Регулярные выражения
Формирование регулярных выражений
Поиск регулярных выражений
Извлечение с помощью регулярных выражений
Резюме
Глава 27. Аннотации
27.1. Зачем нужны аннотации
27.2. Синтаксис аннотаций
27.3. Стандартные аннотации
Устаревание
Непостоянные поля
Двоичная сериализация
Автоматические методы get и set
Хвостовая рекурсия
Unchecked
Native-методы
Резюме
Глава 28. Работа с XML
28.1. Слабоструктурированные данные
28.2. Краткий обзор XML
28.3. Литералы XML
28.4. Сериализация
28.5. Разбор XML
28.6. Десериализация
28.7. Загрузка и сохранение
28.8. Сопоставление с образцом XML
Резюме
Глава 29. Модульное программирование с использованием объектов
29.1. Суть проблемы
29.2. Приложение для работы с рецептами
29.3. Абстракция
29.4. Разбиение модулей на трейты
29.5. Компоновка во время выполнения
29.6. Отслеживание экземпляров модулей
Резюме
Глава 30. Равенство объектов
30.1. Понятие равенства в Scala
30.2. Написание метода равенства
Ловушка № 1. Определение equals с неверной сигнатурой
Ловушка № 2. Изменение equals без изменения hashCode
Ловушка № 3. Определение equals в терминах изменяемых полей
Ловушка № 4. Ошибка в определении equals как отношения эквивалентности
30.3. Определение равенства для параметризованных типов
30.4. Рецепты для equals и hashCode
Рецепт для equals
Рецепт для hashCode
Резюме
Глава 31. Сочетание кода на Scala и Java
31.1. Использование Scala из Java
Основные правила
Типы значений
Объекты-одиночки
Трейты в качестве интерфейсов
31.2. Аннотации
Дополнительные эффекты от стандартных аннотаций
Сгенерированные исключения
Аннотации Java
Написание собственных аннотаций
31.3. Подстановочные типы
31.4. Совместная компиляция Scala и Java
31.5. Интеграция Java 8
Лямбда-выражения и SAM-типы
Использование Stream-объектов Java 8 из Scala
Резюме
Глава 32. Фьючерсы и многопоточность
32.1. Неприятности в раю
32.2. Асинхронное выполнение и Try
32.3. Работа с фьючерсами
Преобразование фьючерсов с помощью map
Преобразование фьючерсов с помощью выражений for
Создание фьючерса: Future.failed Future.successful Future.fromTry и Promise
Фильтрация: filter и collect
Обработка сбоев: failed fallBackTo recover и recoverWith
Отображение обеих возможностей: transform
Объединение фьючерсов: zip Future.foldLeft Future.reduceLeft Future.sequence и Future.traverse
Получение побочных эффектов: foreach onComplete и andThen
Другие методы добавленные в версии 2.12: flatten zipWith и transformWith
32.4. Тестирование с помощью фьючерсов
Резюме
Глава 33. Синтаксический разбор с помощью комбинаторов
33.1. Пример: арифметические выражения
33.2. Запуск парсера
33.3. Основные парсеры — регулярные выражения
33.4. Еще один пример: JSON
33.5. Вывод парсера
Сравнение символьных и буквенно-цифровых имен
33.6. Реализация комбинаторов парсеров
Входные данные парсера
Результаты парсера
Класс Parser
Псевдонимы this
Парсеры отдельных токенов
Последовательная композиция
Альтернативная композиция
Работа с рекурсией
Преобразование результата
Парсеры не считывающие данных
Option и повторение
33.7. Строковые литералы и регулярные выражения
33.8. Лексинг и парсинг
33.9. Сообщения об ошибках
33.10. Сравнение отката с LL(1)
Резюме
Глава 34. Программирование GUI
34.1. Первое Swing-приложение
34.2. Панели и разметки
34.3. Обработка событий
34.4. Пример: программа перевода градусов между шкалами Цельсия и Фаренгейта
Резюме
Глава 35. Электронная таблица SCells
35.1. Визуальная среда
35.2. Разделение введенных данных и отображения
35.3. Формулы
35.4. Синтаксический разбор формул
35.5. Вычисление
35.6. Библиотеки операций
35.7. Распространение изменений
Резюме
Приложение. Скрипты Scala на Unix и Windows
Глоссарий
Об авторах