Scala для начинающих: что нужно знать о языке и с чего начать

Scala для начинающих: что нужно знать о языке и с чего начать Полезное

Scala — статически типизированный язык общего назначения, который объединяет объектно-ориентированное и функциональное программирование. Основная платформа — JVM: код на Scala компилируется в байт-код и работает рядом с Java-библиотеками. Есть и две дополнительные цели компиляции — Scala.js (JavaScript) и Scala Native (машинный код через LLVM).

Ниже — что важно понять до начала изучения: какая версия актуальна, чем 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

Разбор по строкам:

  1. case class Order(...) — класс-запись: компилятор сам создает конструктор без new, сравнение по значению, toString и копирование через copy.
  2. @main def report() — точка входа в стиле Scala 3. Тело задано отступами, без фигурных скобок.
  3. filter(_.paid) — оставляем оплаченные заказы. _ — краткая запись параметра лямбды.
  4. groupBy(_.customer) — получаем Map[String, List[Order]].
  5. mapValues(_.map(_.amount).sum) — для каждого клиента складываем суммы. BigDecimal взят вместо Double, чтобы 1200.50 + 450.00 дало ровно 1650.50 без двоичного округления.
  6. 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 частично это сглаживает.

Дорожная карта до первого артефакта:

  1. Установить JDK и scala, запустить пример выше.
  2. Разобрать val/var/def, case class, match, Option, неизменяемые коллекции.
  3. Создать проект в sbt (стандартный инструмент сборки; альтернатива — Mill) и написать тесты на MUnit или ScalaTest.
  4. Собрать небольшой CLI или HTTP-сервис и выложить в репозиторий — это и есть первый артефакт для портфолио.
  5. Выбрать нишу: 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.

OTUS Журнал
Скидка 5% 14-20 сентября на курсы (popup)