Scala Quick Reference
Everything you need day‑to‑day – functional, object‑oriented, and powerful.
Basic Syntax
// Entry point @main def hello(): Unit = println("Hello, World!") // Main with args @main def main(args: String*): Unit = args.foreach(println) // Semicolons are optional val x = 5 val y = 10 // Comments // Single line /* Multi‑line */ /** Documentation */
Variables & Values
// Immutable (val) – preferred val name = "Alice" val age: Int = 25 val pi = 3.14159 // Mutable (var) – use sparingly var counter = 0 counter = 1 // Lazy values lazy val expensive = computeExpensive() // Type inference val x = 42 // Int val y = 3.14 // Double val z = "hello" // String // Type annotation val score: Double = 95.5 val isActive: Boolean = true
Data Types
Basic Types
Int– 42Double– 3.14Float– 3.14fLong– 42LBoolean– true, falseChar– 'A'String– "Hello"Unit– void (())Nothing– bottom typeAny– top type
Compound Types
Array[T]– Array(1,2,3)List[T]– List(1,2,3)Vector[T]– Vector(1,2,3)Map[K,V]– Map("a" -> 1)Set[T]– Set(1,2,3)Option[T]– Some(1), NoneEither[A,B]– Left("err")Tuple– (1, "Alice")
Type Aliases
type UserID = Int type ValidationResult = Either[String, User]
Control Flow
if / else
if x > 0 then println("positive") else if x == 0 then println("zero") else println("negative") // If as expression val result = if x > 0 then "positive" else "negative"
match (Pattern Matching)
value match case 1 => println("one") case 2 => println("two") case 3 | 4 => println("three or four") case x if x > 10 => println("large") case _ => println("other") // Match as expression val result = value match case 1 => "one" case 2 => "two" case _ => "other"
Loops
// for for i <- 1 to 5 do println(i) // until (excludes upper bound) for i <- 1 until 5 do println(i) // 1,2,3,4 // with step for i <- 1 to 10 by 2 do println(i) // Iterate over collection for item <- list do println(item) // for with index for (item, index) <- list.zipWithIndex do println(s"$index: $item") // for comprehensions val result = for x <- Some(10) y <- Some(20) yield x + y // Some(30) // while var i = 0 while i < 5 do println(i) i += 1
Functions
// Basic function def add(a: Int, b: Int): Int = a + b // Void function (Unit) def log(message: String): Unit = println(message) // Default parameters def greet(name: String, greeting: String = "Hello") = s"$greeting, $name" // Named arguments greet(greeting = "Hi", name = "Alice") // Variadic parameters def sum(numbers: Int*): Int = numbers.sum // Higher‑order functions def applyTwice(f: Int => Int, x: Int): Int = f(f(x)) // Function literals (lambdas) val square = (x: Int) => x * x val square: Int => Int = x => x * x val square = (x: Int) => x * x // Anonymous function shorthand (_) list.map(_ * 2) list.filter(_ > 5) // Partial functions val square: PartialFunction[Int, Int] = case x if x >= 0 => x * x
Collections
List
// Create val list = List(1, 2, 3, 4, 5) val empty = Nil // Operations list.head // first list.tail // rest list(0) // element at index list.length list.isEmpty list.nonEmpty // Add 0 :: list // prepend list :+ 6 // append (O(n)) // Transform list.map(_ * 2) list.filter(_ % 2 == 0) list.reduce(_ + _) list.fold(0)(_ + _) list.flatMap(x => List(x, x * 2)) list.flatten list.distinct list.reverse list.sorted list.sortBy(-_) // Take / Drop list.take(3) list.drop(2) list.takeWhile(_ < 4) list.dropWhile(_ < 4) // Exists / Find list.exists(_ > 3) list.find(_ > 3) // Option list.forall(_ > 0) // Fold list.foldLeft(0)(_ + _) list.foldRight(0)(_ + _) // Zip list.zip(List("a", "b", "c"))
Map
// Create val map = Map("a" -> 1, "b" -> 2, "c" -> 3) // Operations map("a") // 1 (throws if missing) map.get("a") // Some(1) map.getOrElse("d", 0) map.keys map.values map.size // Transform map.mapValues(_ * 2) map.filter(_._2 > 1) map.map { case (k, v) => k -> v * 2 }
Option
// Create val some = Some(42) val none = None // Operations some.get // 42 (dangerous) some.getOrElse(0) some.isDefined some.isEmpty // Transform some.map(_ * 2) // Some(84) some.flatMap(x => Some(x * 2)) some.filter(_ > 10) some.foreach(println) some.orElse(Some(0)) // fold some.fold(0)(_ * 2) // for comprehension for x <- some y <- Some(10) yield x + y
Either
// Create val right: Either[String, Int] = Right(42) val left: Either[String, Int] = Left("Error") // Operations right.isRight right.isLeft right.map(_ * 2) right.flatMap(x => Right(x * 2)) right.fold( left => s"Error: $left", right => s"Success: $right" ) // For comprehension for x <- Right(10) y <- Right(20) yield x + y
Classes & OOP
Basic Class
class Person(val name: String, var age: Int) {
def greet(): String = s"Hello, $name"
def isAdult: Boolean = age >= 18
}
// Usage
val person = Person("Alice", 25)
println(person.greet())
Case Classes
// Auto‑generated: toString, equals, hashCode, copy, apply case class User(id: Int, name: String, email: String) val user1 = User(1, "Alice", "alice@example.com") val user2 = user1.copy(id = 2) // Pattern matching on case classes user match case User(id, name, _) => println(s"$id: $name") case _ => println("unknown")
Objects (Singletons)
object AppConfig {
val version = "1.0.0"
def printVersion() = println(version)
}
Companion Objects
class User(val id: Int, val name: String)
object User {
def apply(id: Int, name: String): User = new User(id, name)
def fromString(s: String): User =
s.split(",") match
case Array(id, name) => User(id.toInt, name)
}
Traits (Interfaces)
trait Greetable {
def name: String
def greet(): String = s"Hello, $name"
}
// Extending trait
class User(val name: String) extends Greetable
// Mixing traits
trait Loggable {
def log(msg: String): Unit = println(s"[LOG] $msg")
}
class User extends Greetable with Loggable
Inheritance
class Animal(val name: String):
def speak(): String = s"$name makes a sound"
class Dog(name: String, val breed: String) extends Animal(name):
override def speak(): String = s"$name barks"
Abstract Classes
abstract class Shape:
def area(): Double
class Circle(val radius: Double) extends Shape:
override def area(): Double = math.Pi * radius * radius
Pattern Matching
// Constant patterns x match case 1 => "one" case 2 => "two" // Variable patterns x match case y if y > 0 => "positive" case _ => "non‑positive" // Constructor patterns (case classes) user match case User(id, _, _) => s"User $id" // Tuple patterns tuple match case (a, b) => s"$a, $b" // List patterns list match case head :: tail => head case Nil => 0 // Type patterns value match case s: String => s"String: $s" case i: Int => s"Int: $i"
Implicits
// Implicit parameter def greet(name: String)(implicit greeting: String) = s"$greeting, $name" implicit val defaultGreeting = "Hello" greet("Alice") // "Hello, Alice" // Implicit conversion (use carefully!) implicit def stringToInt(s: String): Int = s.toInt val x: Int = "42" // 42 // Implicit class (extension methods) implicit class StringOps(s: String) { def isEmail: Boolean = s.contains("@") && s.contains(".") } "alice@example.com".isEmail // true
Futures (Concurrency)
import scala.concurrent.Future import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.duration.* // Create Future val future = Future { Thread.sleep(1000) 42 } // Transform future.map(_ * 2) future.flatMap(x => Future(x * 2)) future.filter(_ > 10) // Await (blocking) import scala.concurrent.Await val result = Await.result(future, 5.seconds) // For comprehension for x <- Future(10) y <- Future(20) yield x + y // Recover future.recover { case e: Exception => 0 }
Error Handling
// try / catch / finally try val result = 10 / 0 catch case e: ArithmeticException => println("Division by zero") case e: Exception => println(s"Error: $e") finally println("Always runs") // Either for error handling def divide(a: Int, b: Int): Either[String, Int] = if b == 0 then Left("Division by zero") else Right(a / b) divide(10, 2) match case Right(result) => println(result) case Left(err) => println(err) // Option for nullable values def toInt(s: String): Option[Int] = try Some(s.toInt) catch case _ => None
Common Built‑in Functions
String
s.lengths.toUpperCases.toLowerCases.trims.split(",")s.contains("sub")s.startsWith("pre")s.endsWith("suf")s.replace("old", "new")s.substring(0, 3)
Math
math.abs(x)math.ceil(x)math.floor(x)math.round(x)math.pow(x, y)math.sqrt(x)scala.util.Random.nextInt(100)scala.util.Random.between(1, 100)
Best Practices
- Use
valovervar– prefer immutability. - Use case classes – for data models.
- Use pattern matching – instead of long if/else chains.
- Use Option – instead of null.
- Use Either – for error handling.
- Use for comprehensions – for sequential operations.
- Avoid mutable state – use immutable collections.
- Use collection functions – map, filter, fold, etc.
- Use traits – for modular design.
- Use implicits – sparingly and with caution.
- Use Futures – for asynchronous code.
- Follow the style guide – use 2 spaces for indentation.
- Use scalafmt – for code formatting.
- Use sbt – for build and dependency management.
📌 Quick Reference
Variables:
Functions:
Collections: List, Map, Set, Option, Either
Pattern matching:
For comprehension:
Case classes: Immutable data holders with auto‑generated methods
Traits: Interfaces with default implementations
Implicits: Implicit parameters, conversions, classes
Futures:
Error handling: Option, Either, try/catch
val (immutable), var (mutable)Functions:
def name(args): ReturnType = bodyCollections: List, Map, Set, Option, Either
Pattern matching:
match with caseFor comprehension:
for ... yieldCase classes: Immutable data holders with auto‑generated methods
Traits: Interfaces with default implementations
Implicits: Implicit parameters, conversions, classes
Futures:
Future for async, Await.result for blockingError handling: Option, Either, try/catch