Scala — статически типизированный язык общего назначения, который объединяет объектно-ориентированное и функциональное программирование. Основная платформа — JVM: код на Scala компилируется в байт-код и работает рядом с Java-библиотеками. Есть и две дополнительные цели компиляции — Scala.js (JavaScript) и Scala Native (машинный код через LLVM).
Содержание
- Коротко о языке и его истории
- Scala 2 и Scala 3: какую версию учить
- Чем Scala отличается от Java и Kotlin
- Три понятия, которые путают новички
- Первая программа: от установки до результата
- Типичные ошибки новичка
- Если не получилось запустить
- Где применяется Scala и что учить дальше
- Выводы
- Где применяется / связь с практикой
- FAQ
Ниже — что важно понять до начала изучения: какая версия актуальна, чем Scala отличается от Java и Kotlin, как выглядит первая программа, на каких ошибках спотыкаются новички и где язык реально востребован.
Коротко о языке и его истории
Scala создал Мартин Одерски в швейцарской лаборатории EPFL. Работа над языком началась в 2001 году, первый публичный релиз для JVM вышел в начале 2004 года. Была и версия для .NET, но ее поддержку давно прекратили, поэтому сегодня говорить о Scala на .NET не стоит.
Ключевая идея языка — «масштабируемость» (отсюда название: Scalable Language). Одни и те же механизмы — функции, классы, трейты, сопоставление с образцом — работают и в скрипте на десять строк, и в большой системе. Это не значит, что проект на Scala масштабируется «сам»: речь о выразительности языка, а не об архитектуре.
Scala 2 и Scala 3: какую версию учить
В 2021 году вышла Scala 3 — крупная переработка языка (компилятор Dotty). На сентябрь 2026 года новичку стоит начинать со Scala 3. Scala 2 развивается как поддерживаемая ветка 2.13, и ее все еще много в существующих проектах.
| Scala 2.13 | Scala 3 | |
|---|---|---|
| Статус | поддерживаемая legacy-ветка | основная линия развития |
| Синтаксис блоков | только фигурные скобки | скобки или отступы (optional braces) |
| Точка входа | object Main { def main(args: Array[String]) ... } |
@main def run() = ... (старый вариант тоже работает) |
| Неявные параметры | implicit |
given / using (implicit оставлен для совместимости) |
| Перечисления | через sealed trait + объекты | ключевое слово enum |
| Где встречается | Apache Spark, старые сервисы | новые проекты, библиотеки экосистемы Typelevel и ZIO |
Практический вывод: учите Scala 3, но будьте готовы читать код 2.13. Если цель — работа с Apache Spark, сверяйтесь с версией Scala, под которую собран ваш Spark: он исторически живет на ветке 2.x.
Чем Scala отличается от Java и Kotlin
Все три языка работают на JVM и могут вызывать код друг друга. Разница — в том, какой стиль программирования язык поощряет.
| Критерий | Java | Kotlin | Scala |
|---|---|---|---|
| Основной стиль | ООП, функциональные элементы с Java 8 | ООП + прагматичная функциональщина | ООП и ФП на равных |
| Вывод типов | локальный (var с Java 10) |
развитый | развитый |
| Сопоставление с образцом | развивается с Java 16-21 | when |
match — одна из центральных конструкций |
| Порог входа | ниже | ниже | выше из-за системы типов и ФП-библиотек |
| Типичные ниши | корпоративный бэкенд | Android, бэкенд | обработка данных, высоконагруженный бэкенд, финтех |
Совместимость с Java нужно понимать точно. Scala свободно использует Java-библиотеки, а Java может вызывать Scala-код. Но некоторые возможности Scala (например, given, типы высших порядков, значения по умолчанию в сложных сигнатурах) из Java вызывать неудобно или нельзя напрямую. Scala — не «надмножество Java»: Java-код компилятором Scala не собирается.
Три понятия, которые путают новички
val— неизменяемая ссылка: присвоить новое значение нельзя. Это вариант по умолчанию.var— изменяемая переменная. Нужна редко: в основном в локальных циклах и оптимизациях.def— метод: выражение вычисляется при каждом вызове, а не один раз.
Упрощение: val запрещает переприсваивание, но не делает объект внутри неизменяемым. val buf = scala.collection.mutable.ListBuffer(1) можно изменить через buf += 2. Неизменяемость дают неизменяемые коллекции (List, Map, Vector по умолчанию) и case class.
Еще одна пара: типизация в Scala статическая (типы проверяет компилятор) и при этом с выводом типов — писать тип явно нужно не везде. В val n = 5 компилятор сам выведет Int, но передать n туда, где ждут String, не даст. Точка с запятой в конце строки необязательна.
Первая программа: от установки до результата
Для Scala 3 достаточно установить JDK (подойдет актуальная LTS, например 21 или 25) и инструмент scala. Начиная с Scala 3.5 команда scala — это Scala CLI: она сама скачает компилятор и запустит файл без настройки проекта. Удобнее всего ставить через установщик Coursier (cs setup).
Минимальный полный пример — отчет по оплаченным заказам. Сохраните как Main.scala:
case class Order(id: Int, customer: String, amount: BigDecimal, paid: Boolean)
@main def report(): Unit =
val orders = List(
Order(1, "anna", BigDecimal("1200.50"), paid = true),
Order(2, "boris", BigDecimal("300.00"), paid = false),
Order(3, "anna", BigDecimal("450.00"), paid = true),
Order(4, "vera", BigDecimal("990.90"), paid = true)
)
val paidByCustomer: Map[String, BigDecimal] =
orders
.filter(_.paid)
.groupBy(_.customer)
.view.mapValues(_.map(_.amount).sum).toMap
paidByCustomer.toList.sortBy(_._1).foreach { (name, total) =>
println(s"$name: $total")
}
val unpaid = orders.count(o => !o.paid)
println(s"Неоплаченных заказов: $unpaid")
Запуск:
scala run Main.scala
В консоли появится (после строк о компиляции при первом запуске):
anna: 1650.50
vera: 990.90
Неоплаченных заказов: 1
Разбор по строкам:
case class Order(...)— класс-запись: компилятор сам создает конструктор безnew, сравнение по значению,toStringи копирование черезcopy.@main def report()— точка входа в стиле Scala 3. Тело задано отступами, без фигурных скобок.filter(_.paid)— оставляем оплаченные заказы._— краткая запись параметра лямбды.groupBy(_.customer)— получаемMap[String, List[Order]].mapValues(_.map(_.amount).sum)— для каждого клиента складываем суммы.BigDecimalвзят вместоDouble, чтобы 1200.50 + 450.00 дало ровно 1650.50 без двоичного округления.sortBy(_._1)— сортируем по имени, иначе порядок ключейMapне гарантирован.
Исходный список orders при этом не меняется: каждая операция возвращает новую коллекцию. Это и есть функциональный стиль на практике.
Типичные ошибки новичка
Ошибка 1. Переприсваивание val.
val total = 10
total = 20
Результат — ошибка компиляции, программа не соберется:
Reassignment to val total
Исправление: если значение действительно меняется — var total = 10. Но чаще правильнее завести новое имя (val newTotal = total + 10) и не менять старое.
Ошибка 2. Обращение к отсутствующему ключу Map.
val prices = Map("tea" -> 100, "coffee" -> 150)
println(prices("juice"))
Код компилируется, но при запуске падает:
java.util.NoSuchElementException: key not found: juice
Исправление — получить Option и явно обработать отсутствие:
val prices = Map("tea" -> 100, "coffee" -> 150)
prices.get("juice") match
case Some(p) => println(s"Цена: $p")
case None => println("Такого товара нет")
println(prices.getOrElse("tea", 0))
Вывод:
Такого товара нет
100
Option — базовая идея Scala: вместо null значение либо есть (Some), либо его нет (None), и компилятор подталкивает обработать оба случая.
Точный текст сообщений компилятора может меняться между версиями Scala 3; суть ошибки от этого не меняется.
Если не получилось запустить
scala: command not found— инструмент не установлен или не вPATH. Переоткройте терминал послеcs setup, проверьтеscala version.- Ошибки про JDK или версию класса — не установлен JDK или он слишком старый. Проверьте
java -version. - Код из статьи 2019 года не компилируется — вероятно, он написан под Scala 2 (например, процедурный синтаксис
def f() { ... }). Сверьте версию в примере. - Ошибка из-за отступов в Scala 3 — смешаны табы и пробелы или строка тела сдвинута не на тот уровень. Выровняйте отступы или оберните блок в фигурные скобки.
Где применяется Scala и что учить дальше
Scala — язык общего назначения, но на рынке у него несколько устойчивых ниш:
- Обработка больших данных. Apache Spark написан на Scala, и Scala API — один из основных способов работы с ним. Отсюда спрос в дата-инжиниринге.
- Высоконагруженный бэкенд. Сервисы на функциональных стеках (Cats Effect, ZIO), акторная модель (Akka и ее открытый форк Apache Pekko), веб-фреймворк Play.
- Финтех и стриминг — там, где ценят строгую типизацию и предсказуемую работу с конкурентностью.
Честно о минусах: вакансий на Scala меньше, чем на Java или Kotlin, а порог входа выше. Компиляция крупных проектов заметно медленнее, чем у Java, хотя инкрементальная сборка в sbt частично это сглаживает.
Дорожная карта до первого артефакта:
- Установить JDK и
scala, запустить пример выше. - Разобрать
val/var/def,case class,match,Option, неизменяемые коллекции. - Создать проект в sbt (стандартный инструмент сборки; альтернатива — Mill) и написать тесты на MUnit или ScalaTest.
- Собрать небольшой CLI или HTTP-сервис и выложить в репозиторий — это и есть первый артефакт для портфолио.
- Выбрать нишу: Spark для данных или функциональный бэкенд на Cats Effect/ZIO.
С опытом Java этот путь обычно проходится быстрее, без него — дольше: срок сильно зависит от регулярности практики.
Выводы
- Scala — статически типизированный язык для JVM, где ООП и функциональный стиль равноправны; есть также Scala.js и Scala Native.
- Новичку в 2026 году стоит учить Scala 3, но уметь читать код 2.13 — на нем много существующих проектов, включая экосистему Spark.
- Базовые понятия для старта:
valпротивvar,case class,match,Optionвместоnull, неизменяемые коллекции. - Основные ниши — обработка данных и высоконагруженный бэкенд; вакансий меньше, чем на Java, а порог входа выше.
Где применяется / связь с практикой
Освойте тему на практике
Scala лучше всего осваивается на задачах, близких к реальным: сервис с тестами, работа с конкурентностью, обработка потоков данных. Если нужен системный путь от синтаксиса до production-кода на Scala 3 с разбором функциональных библиотек, посмотрите курс по Scala-разработке. Чтобы сначала оценить формат и уровень, подойдут бесплатные открытые уроки Otus.
FAQ
Нужно ли знать Java перед Scala?
Не обязательно, но полезно понимать JVM и уметь читать Java-код: многие библиотеки и сообщения об ошибках приходят из Java-мира.
Можно ли писать на Scala Android-приложения?
Технически это возможно, но на практике для Android выбирают Kotlin: официальная поддержка инструментов и документации Google ориентирована на него.
Что выбрать для сборки: sbt или scala-cli?
Для скриптов и первых экспериментов удобен scala (Scala CLI), для многомодульных проектов и работы в команде стандартом остается sbt.



