Перейти к основному содержимому

Scala — итоги

Разработчику Аналитику Тестировщику Архитектору Инженеру

Кратко — что стоит унести из раздела "Scala". Если пункт кажется туманным — откройте указанную главу или оглавление.


FAQ — Часто задаваемые вопросы

Типичные сбои и ситуации, с которыми сталкиваются новички после раздела. Здесь — что делать и где копать в главах.

Вопрос. scala-cli run падает с "Unsupported class file major version" — JDK вроде установлен.

Ответ. Версия JDK должна быть не ниже, чем требует Scala (для Scala 3 — JDK 17+). Проверьте java -version и JAVA_HOME; sbt/scala-cli могут подхватить другую Java из PATH. Подробнее здесь — первая программа, архитектура JVM.

Вопрос. Первый запуск sbt качает полинтернета — это нормально?

Ответ. sbt тянет Scala, zinc, зависимости в локальный кэш (~/.ivy2, ~/.sbt). Последующие сборки быстрее; для учебных скриптов проще scala-cli. Подробнее здесь — первая программа.

Вопрос. "Could not find an implicit value for ExecutionContext" при Future.

Ответ. Future требует неявный ExecutionContext в области видимости (import scala.concurrent.ExecutionContext.Implicits.global или свой пул). Без него компилятор не знает, где выполнять callback. Подробнее здесь — архитектура JVM, функции.

Вопрос. option.get бросил NoSuchElementException — Option же "безопасный".

Ответ. get на Noneнамеренно аварийный. Используйте getOrElse, fold, pattern matching или match. Подробнее здесь — типы и match, приложения.

Вопрос. Перепутал val и var — объект "меняется", хотя объявил val.

Ответ. val запрещает переприсвоение ссылки; mutable-коллекция внутри всё ещё меняется. Для неизменяемого состояния — immutable.Seq, обновление через :+ / updated. Подробнее здесь — основы, типы.

Вопрос. Java-библиотека вернула null — NPE в Scala-коде.

Ответ. На границе JVM оборачивайте в Option(...) или используйте @Nullable аннотации и сразу Option. Scala 3 улучшает null-safety, но Java interop остаётся зоной риска. Подробнее здесь — архитектура JVM.

Вопрос. case class vs обычный class — когда что?

Ответ. case class даёт equals/hashCode, copy, unapply для pattern matching — идеален для DTO и ADT. Обычный class — для инкапсуляции, наследования, mutable state. Подробнее здесь — типы и match.

Вопрос. Компилятор: "match may not be exhaustive" — вроде все case покрыты.

Ответ. Для sealed hierarchy нужны все подтипы; для String/Int — default _. Включите -Xfatal-warnings на учебном проекте. Подробнее здесь — типы и match.

Вопрос. For-comprehension выглядит как цикл, а внутри Option/Future — как читать?

Ответ. Это синтаксический сахар над flatMap/map: каждый <- — шаг, который может "оборваться" (None/ failed Future). Перепишите for в .flatMap для понимания. Подробнее здесь — функции, приложения.

Вопрос. Создал Future { ... }, но код внутри не выполняется.

Ответ. Future ленив до первого callback и нужен ExecutionContext; в main программа может завершиться раньше. Используйте Await.result в учебных примерах или scala-cli с @main и явным ожиданием. Подробнее здесь — архитектура.

Вопрос. Новичку советуют Akka/Play — стоит ли начинать с них?

Ответ. Сначала язык и stdlib: основы, типы, приложения. Akka/Spark — после понимания JVM, Future и неизменяемости. Подробнее здесь — оглавление.

Вопрос. Tutorial на Scala 2, а у меня Scala 3 — object App, _ для wildcard.

Ответ. Scala 3: @main вместо App, _ в типах заменён на ?, новый синтаксис indent. Смотрите официальный migration guide и статьи раздела с пометкой Scala 3. Подробнее здесь — история, первая программа.

Вопрос. @main def run() не находится как точка входа в sbt.

Ответ. В sbt укажите Compile / run / mainClass или используйте scala-cli run file.scala. Для sbt-проекта иногда проще object Main extends App (2.x) или явный mainMethod в build.sbt. Подробнее здесь — первая программа, приложения.

Вопрос. "Type inference failed" на простом val xs = List(1,2,3).map(...)".</p> <p class="faq-a"><span class="faq-label">Ответ.</span> Компилятор не сузил <strong>общий тип</strong> (часто из-за смешения Int/Doubleили polymorphic map). Добавьте явный типval xs: List[Int] = ...или.map((x: Int) => ...)`. Подробнее здесь — типы.

Вопрос. Как "обновить" элемент в immutable List?

Ответ. Создаётся новая структура: list.updated(i, v) или list.patch. Для частых обновлений по ключу — Map или Vector. Подробнее здесь — основы, типы.

Вопрос. Маленький скрипт на scala-cli жрёт много RAM — JVM так устроена?

Ответ. JVM стартует с heap по умолчанию; для CLI можно -Xmx256m. Для одноразовых утилит scala-cli нормален; для продакшена настраивают GC и limits. Подробнее здесь — архитектура JVM.

Вопрос. Either — Left это ошибка или успех? Путаю каждый раз.

Ответ. Конвенция Scala: Left — ошибка, Right — успех (Right = "правильный"). В своём API зафиксируйте тип Either[String, A] и придерживайтесь. Подробнее здесь — типы, приложения.

Вопрос. Строка s"$name age" vs f"$pi%.2f" — когда f-string?

Ответ. sинтерполяция; f — форматирование как printf. Для логов и UI чаще s; для чисел с точностью — f. Подробнее здесь — основы.

Вопрос. Несколько trait с одинаковым методом — откуда берётся реализация?

Ответ. Сработает linearization (C3) — порядок mixin в объявлении class. При конфликте нужен явный super или override. Подробнее здесь — основы ООП в Scala.

Вопрос. lazy val в многопоточке инициализировался дважды — возможно?

Ответ. lazy val по spec thread-safe при первой инициализации; гонки возможны, если внутри side effects. Для тяжёлой инициализации используйте lazy val осознанно или explicit lock. Подробнее здесь — архитектура.

Вопрос. Рекурсия без @tailrec — StackOverflowError на большом n.

Ответ. JVM не оптимизирует хвост без аннотации @tailrec (и truly tail call). Перепишите на цикл или fold; компилятор предупредит, если tailrec невозможен. Подробнее здесь — функции.

Вопрос. Source.fromFile — файл не закрывается, дескriptor leak.

Ответ. Оборачивайте в Using.resource(Source.fromFile(...)) { ... } или scala.util.Using. Подробнее здесь — приложения.

Вопрос. Implicit conversion "магически" превращает Int в RichInt — это ещё актуально?

Ответ. В Scala 3 implicit conversions ограничены; предпочитайте extension methods и given instances. Старые туториалы с implicit def читайте с осторожностью. Подробнее здесь — история, функции.

Вопрос. HTTP-сервер из приложений не отвечает с другого компьютера в сети.

Ответ. InetSocketAddress(8080) слушает все интерфейсы, но firewall может блокировать. Проверьте URL, bind address и что процесс жив. Подробнее здесь — приложения, HTTP в энциклопедии.

Вопрос. Пришёл из Java — Scala кажется "Java с лишним синтаксисом".

Ответ. Выигрыш — в композиции и типах: Option, match, for-comprehension, case class. Пишите новый код в functional style, Java interop подключайте точечно. Подробнее здесь — основы, Java.

Вопрос. uPickle/Jason decode падает на поле — как отладить JSON-модель?

Ответ. Сверьте имена полей case class с JSON (camelCase vs snake), defaults для optional. В circe — decodeAccumulating для списка ошибок. Подробнее здесь — приложения.

Вопрос. Куда двигаться после консольных примеров — Spark, Akka или Android?

Ответ. Зависит от цели: данные — Spark (архитектура); concurrent services — Akka/Pekko; Android — Kotlin чаще, Scala возможен. База раздела одинакова. Подробнее здесь — оглавление.

Вопрос. Scala с нуля — как начать учить язык на JVM?

Ответ. JDK 17+, scala-cli или sbt, первая программа с @main. Маршрут — первая программаосновы. Подробнее здесь — оглавление.

Вопрос. Scala 3 vs Scala 2 — что учить новичку в 2025?

Ответ. Раздел ориентирован на Scala 3: @main, given/using, улучшенный match. Старый код 2.x читается с migration guide. Подробнее здесь — история, первая программа.

Вопрос. Scala или Java — что выбрать для backend?

Ответ. Java — максимум вакансий и фреймворков; Scala — FP, Spark, Akka, выразительные типы. Оба на JVM, interop прямой. Подробнее здесь — основы, Java.

Вопрос. Scala или Kotlin — в чём разница?

Ответ. Kotlin — прагматичный JVM для Android/backend; Scala — глубже FP, case class/match, for-comprehension, Spark. Подробнее здесь — оглавление, Kotlin.

Вопрос. Как установить Scala на Windows — scala-cli vs sbt?

Ответ. Скачайте Coursier/scala-cli или sbt; нужен JDK 17+. Проверка: scala --version. Подробнее здесь — первая программа.

Вопрос. Apache Spark Scala tutorial — нужен ли Scala для Spark?

Ответ. Spark API есть на Scala, Java, Python; Scala — "родной" DSL и типы для data pipeline. Сначала основы языка, потом архитектура JVM.

Вопрос. case class Scala example — зачем нужен?

Ответ. Immutable data + copy, equals, unapply для pattern matching одной строкой. DTO и ADT в idiomatic Scala. Подробнее здесь — типы и match.

Вопрос. Pattern matching Scala — как разобрать Option?

Ответ. x match { case Some(v) => ...; case None => ... } — исчерпывающие ветки. Предпочтительнее .get. Подробнее здесь — типы и match.

Вопрос. for comprehension Scala Option Future — что это?

Ответ. Синтаксический сахар над flatMap/map для цепочек шагов с коротким замыканием при None/failed Future. Подробнее здесь — функции, приложения.

Вопрос. implicit vs given Scala 3 — что изменилось?

Ответ. В Scala 3 given/using заменяют implicit для type class и контекстов; читаемость выше. Старые туториалы с implicit def — legacy. Подробнее здесь — история, функции.

Вопрос. Akka Scala actor model — с чего начать?

Ответ. После основ и JVM-архитектуры — Pekko/Akka docs: Actor, mailbox, supervision. Не прыгайте в Akka до Future и immutability. Подробнее здесь — архитектура.

Вопрос. Martin Odersky Scala course Coursera — стоит ли проходить?

Ответ. Классический вход в FP на Scala; дополняет раздел практикой. Параллельно — первая программа и типы в энциклопедии.

Вопрос. Scala immutable List map filter example?

Ответ. List(1,2,3).filter(_ > 1).map(_ * 2) — новая коллекция, исходник не меняется. Подробнее здесь — основы, функции.

Вопрос. Scala play framework tutorial — когда подключать?

Ответ. После консольных приложений и понимания HTTP. Play — full-stack MVC на JVM; для API иногда достаточно http4s/tapir. Подробнее здесь — архитектура.

Вопрос. Scala.js — можно ли писать фронтенд на Scala?

Ответ. Да, Scala.js компилирует в JavaScript; общий код с backend на Scala. Нишевее, чем TypeScript. Упоминание платформ — в истории, оглавлении.

Вопрос. sbt compile slow — как ускорить сборку?

Ответ. SSD, больше RAM, -J-Xmx, incremental compile, не тянуть лишние subprojects. Для скриптов — scala-cli быстрее стартует. Подробнее здесь — первая программа.

Вопрос. trait vs abstract class Scala — что выбрать?

Ответ. trait — mixin, linearization, нет конструктора; abstract class — если нужен конструктор или Java interop. Подробнее здесь — основы.

Вопрос. Scala Future async example — как не блокировать поток?

Ответ. Future { ... } на ExecutionContext; не вызывайте Await.result в prod-коде request thread. Callbacks через map/flatMap/for. Подробнее здесь — архитектура, функции.

Вопрос. Functional programming Scala book — с чего читать по-русски?

Ответ. Начните с раздела: основыфункции; книги Odersky/Svensson — после первых программ. Подробнее здесь — оглавление.

Вопрос. Hello World Scala 3 @main example?

Ответ. @main def hello() = println("Hello, World!"), запуск scala-cli run hello.scala. Подробнее здесь — первая программа.

Вопрос. Scala JSON parse circe uPickle — как выбрать?

Ответ. uPickle — легко для учёбы; circe — экосистема Cats/Typelevel. В приложениях — uPickle пример. Подробнее здесь — приложения.

Вопрос. ZIO Cats Effect Scala — нужны ли сразу?

Ответ. Нет — сначала stdlib, Future, Option. ZIO/Cats — следующий уровень effect systems после архитектуры.

Вопрос. Scala type hierarchy Any AnyVal Ref — зачем знать?

Ответ. Понимание value classes, boxing, null на JVM помогает при interop с Java и performance. Подробнее здесь — типы, архитектура.


Что запомнить

Scala — мультипарадигмальный язык на JVM (и Scala.js/Native): функциональный стиль (map, Option, immutability) с ООП и мощной системой типов. В разделе ориентир — Scala 3.

Основные особенности:

  • val/var, case class, pattern matching — модель данных;
  • For-comprehension — работа с Option, Future, коллекциями;
  • JVM interop — Java-библиотеки и null на границе;
  • Инструменты — sbt, scala-cli, Metals IDE.

Области: бэкенд (Akka/Pekko), big data (Spark), DSL и библиотеки (Cats, ZIO — за рамками базового курса).

Три правила:

  1. Предпочитайте immutable API и явные типы ошибок (Option/Either);
  2. На границе с Java оборачивайте null;
  3. Осваивайте язык до фреймворка — Play/Akka после приложений.

Куда идти дальше

ТемаРаздел
Java (JVM-база)Java — о разделе
Kotlin (JVM, лаконичность)Kotlin — о разделе
Haskell (чистый FP)Haskell — о разделе

См. также

Другие статьи этого же раздела в боковом меню (как на странице "О разделе").