Scala Basics
This page provides an overview of the Scala language features required to complete the workshop.
Values
In Scala you can assign values to names using val
:
val aNumber = 3
Optionally, you can explicitly assign a type to the val:
val aNumber: Int = 3
Scala is a statically typed language: every value has a type. Types help us to
detect mistakes early, during compilation, rather than later, when the program
is used. When we do not specify the type for a val
Scala guesses, or infers,
an appropriate type
Definitions
Functions can be defined with def
:
def functionName(argument: TypeOfArgument): TypeOfReturn =
body
for example
def sum(a: Int, b: Int): Int =
a + b
Case classes
A case class is used to create a new type combining already existing ones.
For example Block
indicates a block in the Snake game and contains the x
and y
coordinates of the block.
case class Block(x: Int, y: Int)
You can create a block like this:
val block = Block(1, 2)
If you have a block, you can read its x
and y
attributes using block.x
and block.y
.
If you prefer, you can specify the variable name when you create a case class instance:
val block = Block(x=1, y=2)
Enums
enum
can be used to define a type with a finite set of named values. For example:
enum Direction:
case Up, Down, Left, Right
This means that any Direction
can take only one of the values Up
, Down
, Left
or Right
.
The only way to create a Direction
is to access one of the cases:
val right = Direction.Right
List
A list is a sequence of values. List[Block]
means that all the elements of the list are a Block
.
Here are a few useful operations on lists:
- You can obtain the length of the list with
.length
:
List(1, 2, 3).length // res0: Int = 3
- You can extract the first element of the list with
.head
:
List(1, 2, 3).head // res0: Int = 1
- You can obtain a list without the first element with
.tail
:
List(1, 2, 3).tail // res0: List[Int] = List(2, 3)
- You can add a new element to the beginning a list with
::
:
0 :: List(1, 2, 3) // res0: List[Int] = List(0, 1, 2, 3)
- You can check if a list contains an element with:
.contains
:
List(1, 2, 3).contains(2) // res0: Boolean = true
- You can obtain a list without the last n elements with
.dropRight
:
List(1, 2, 3).dropRight(2) // res0: List[Int] = List(1)
- You can obtain a list without the first n elements with
.drop
:
List(1, 2, 3).drop(2) // res0: List[Int] = List(3)
If expressions
If expressions are similar to other languages
def evenTest(x: Int): String =
if x % 2 == 0 then "x is even"
else "x is odd"
To test multiple conditions you can chain conditions with else if
:
def binary(x: Int): String =
if x == 0 then "I know 0!"
else if x == 1 then "I know 1!"
else "What is this?"
Pattern matching
Finally, Scala supports pattern matching. This feature accepts many syntaxes but
for this workshop we will only use it with enum
, Option
and case classes.
def directionToString(direction: Direction): String =
direction match
case Direction.Up => "You chose Up"
case Direction.Down => "You chose Down"
case Direction.Right => "You chose Right"
case Direction.Left => "You chose Left"
After List
, another common type in Scala is Option[T]
which is used to express that a T
might not be provided.
For example in Snake.scala
, updateGame
is called periodically to advance the game.
During that time the user might have pressed a button or not.
You can use pattern matching to process Option
s:
def matchOptionExample(maybeNumber: Option[Int]): String
maybeNumber match
case Some(number) => "I received number " + number
case None => "I did not receive any number"