Frequently asked questions and answers about Scala. Questions are categorized for quick access to the information you need.
TL;DR
- Version Choice: Scala 3 for new projects, Scala 2.12/2.13 when using Spark
- val vs var: Always prefer
val(immutable)- Instead of null: Use
Option,Some,Nonefor safe null handling- IDE: IntelliJ IDEA + Scala plugin (most mature)
- Performance: Equivalent to Java, watch out for collection chaining and lambda usage
General#
General questions about learning Scala.
Should I learn Scala?
Yes. Scala is particularly useful in these cases:
- Large-scale data processing (Apache Spark)
- Distributed systems (Akka)
- Projects where type safety is important
- When you want to learn functional programming
Should I learn Scala 2 or Scala 3?
It depends on your situation.
- New projects: Scala 3 recommended
- Using Spark: Scala 2.12/2.13 (Spark doesn’t support Scala 3 yet)
- Maintaining existing projects: Match the project version
The core concepts are the same in both versions, so learning one makes it easy to adapt to the other.
Is Scala difficult?
The basics are not difficult. If you have Java experience, you can pick up the basic syntax quickly.
Difficult parts:
- Advanced type system (variance, type classes)
- Complex usage of implicits
- Macros/metaprogramming
Learn gradually. You don’t need to know all advanced features from the start.
Key Points
- Scala 3 recommended for new projects, maintain Scala 2 when using Spark
- Basics are approachable, but advanced type system requires gradual learning
Syntax#
Questions about Scala syntax.
What’s the difference between val and var?
val x = 10 // Immutable (cannot be changed)
// x = 20 // Compile error!
var y = 10 // Mutable (can be changed)
y = 20 // OKRecommendation: Always use val when possible.
What’s the difference between def, val, and lazy val?
// Computed every time
def computed = { println("computing"); 42 }
computed // Prints "computing"
computed // Prints "computing"
// Computed once (eagerly)
val eager = { println("eager"); 42 } // Prints "eager"
eager // No output
eager // No output
// Computed once (lazily)
lazy val deferred = { println("lazy"); 42 }
// No output yet
deferred // Prints "lazy"
deferred // No outputDo I need semicolons?
Usually not. Scala automatically infers semicolons at the end of lines.
val x = 1
val y = 2
// Multiple statements on one line require semicolons
val a = 1; val b = 2What is Unit?
Unit is similar to Java’s void. It indicates no meaningful value is returned.
def printMessage(): Unit = println("Hello")
// The only value of Unit is ()
val unit: Unit = ()Key Points
- Use
val(immutable) by default,var(mutable) only when necessarylazy valinitializes on first access,defrecomputes on every call- Semicolons only needed when writing multiple statements on one line
Functional Programming#
Questions about functional programming patterns.
What are Option, Some, and None?
Option safely represents the presence or absence of a value:
def findUser(id: Int): Option[String] =
if (id > 0) Some(s"User$id") else None
findUser(1) // Some("User1")
findUser(-1) // None
// Usage
findUser(1).getOrElse("Unknown") // "User1"
findUser(-1).getOrElse("Unknown") // "Unknown"Use Option instead of null!
What’s the difference between map and flatMap?
val opt = Some(5)
// map: A => B
opt.map(_ * 2) // Some(10)
// flatMap: A => Option[B]
opt.flatMap(x => if (x > 0) Some(x * 2) else None) // Some(10)
// The difference
val nested = Some(Some(5))
nested.map(_.map(_ * 2)) // Some(Some(10))
nested.flatMap(_.map(_ * 2)) // Some(10)How does for comprehension work?
For comprehensions are transformed into flatMap, map, and withFilter:
// for comprehension
for {
x <- Some(1)
y <- Some(2)
} yield x + y
// Transformed to
Some(1).flatMap(x =>
Some(2).map(y =>
x + y
)
)
// Result: Some(3)Key Points
- Use
Optionto safely replace null,getOrElsefor default valuesmaptransforms values,flatMapflattens nested containers- For comprehension is a more readable expression of
flatMap/mapchains
Troubleshooting#
Common issues and solutions during development.
“implicit not found” error
could not find implicit value for parameter ord: Ordering[MyClass]Solution: Define or import the required implicit instance.
case class Person(name: String, age: Int)
// Define instance
implicit val personOrdering: Ordering[Person] = Ordering.by(_.age)
// Or define in companion object
object Person {
implicit val ordering: Ordering[Person] = Ordering.by(_.age)
}“value xxx is not a member of yyy”
Extension methods may not be imported:
import cats.syntax.all._ // Cats extension methods
import zio.prelude._ // ZIO extension methodsCompilation is too slow
- Use incremental compilation:
sbt ~compile - Parallel compilation:
parallelExecution := true - Use cache: Keep
.bspdirectory
Red underlines in IntelliJ
- File → Invalidate Caches → Restart
- Reload in sbt tab
- Build → Rebuild Project
Key Points
- “implicit not found” resolved by defining/importing required type class instances
- Extension method errors: check correct import statements
- Compilation speed improvement: use incremental compilation (
sbt ~compile)
Performance#
Questions about Scala performance.
Is Scala slower than Java?
In most cases, performance is similar. Scala compiles to JVM bytecode, so runtime performance is comparable to Java.
What to watch out for:
- Lambdas and higher-order functions create objects
- Collection chaining can create intermediate collections
- Use
@tailrecto verify tail recursion optimization
Do immutable collections affect performance?
Scala’s immutable collections use structural sharing to be efficient:
val list1 = List(1, 2, 3)
val list2 = 0 :: list1 // Reuses list1's dataIf performance is critical, use Array or mutable collections.
Key Points
- Scala runtime performance equals Java (JVM bytecode)
- Immutable collections are efficient via structural sharing, use
Arrayfor extreme performance- Verify tail recursion optimization with
@tailrec
Tools#
Questions about development tool choices.
Which IDE should I use?
- IntelliJ IDEA + Scala plugin: Most mature
- VS Code + Metals: Lightweight and fast
Which build tool?
- sbt: Standard Scala build tool
- Mill: Faster alternative
- Gradle: For mixed Java projects
Which testing framework?
- ScalaTest: Most widely used, various styles
- MUnit: Simple and lightweight (recommended for Scala 3)
- Specs2: BDD style
Key Points
- IDE: IntelliJ IDEA (mature) or VS Code + Metals (lightweight)
- Build: sbt (standard), Mill (fast), Gradle (Java integration)
- Testing: ScalaTest (general purpose), MUnit (Scala 3 lightweight)
Additional Questions#
If you have more questions: