Scala Basic Syntax
This chapter introduces the basic syntax rules of Scala, including program structure, comments, identifiers, keywords, and other core concepts.
Program Structure
Hello World Program
Let's start with the classic Hello World program:
// Scala 3 style (recommended)
@main def hello(): Unit =
println("Hello, World!")
// Or traditional main method
object HelloWorld {
def main(args: Array[String]): Unit = {
println("Hello, World!")
}
}Program Components
A Scala program typically contains the following parts:
- Package declaration (optional)
- Import statements (optional)
- Class, object, trait definitions
- Method and function definitions
// 1. Package declaration
package com.example.myapp
// 2. Import statements
import scala.collection.mutable.ListBuffer
import java.util.Date
// 3. Object definition
object MyApp {
// 4. Method definition
def main(args: Array[String]): Unit = {
println("My Scala Application")
}
}Comments
Scala supports three types of comments:
Single-line Comments
// This is a single-line comment
val x = 10 // End of line commentMulti-line Comments
/*
* This is a multi-line comment
* Can span multiple lines
*/
val y = 20
/* Simple multi-line comment */Documentation Comments
/**
* This is a documentation comment for generating API documentation
* @param name Username
* @param age Age
* @return Formatted user information
*/
def formatUser(name: String, age: Int): String = {
s"User: $name, Age: $age"
}Identifiers
Identifiers are used to name variables, methods, classes, and other program elements.
Identifier Rules
- Alphanumeric identifiers: Start with a letter or underscore, followed by letters, numbers, or underscores
val name = "Alice"
val user_age = 25
val MAX_SIZE = 100
val _private = "hidden"- Operator identifiers: Consist of operator characters
val + = "plus"
val :: = "cons"
val <=> = "compare"- Mixed identifiers: Alphanumeric identifier followed by underscore and operator identifier
val unary_+ = "positive"
val myList_+ = "append"- Literal identifiers: Any string enclosed in backticks
val `class` = "reserved word"
val `my variable` = "with spaces"
val `2nd-item` = "starts with number"Naming Conventions
// Variables and methods: camelCase
val firstName = "John"
def calculateTotal() = 100
// Constants: uppercase letters and underscores
val MAX_RETRY_COUNT = 3
val DEFAULT_TIMEOUT = 30
// Classes and traits: PascalCase
class UserAccount
trait Serializable
// Packages: lowercase
package com.example.utilsKeywords
Scala's reserved keywords cannot be used as identifiers:
Basic Keywords
abstract case catch class def
do else extends false final
finally for if implicit import
lazy match new null object
override package private protected return
sealed super this throw trait
try true type val var
while with yieldScala 3 New Keywords
enum export given then usingSoft Keywords
These have special meaning in specific contexts:
as derives end extension infix
inline opaque open transparent usingLiterals
Integer Literals
val decimal = 123 // Decimal
val hex = 0xFF // Hexadecimal
val octal = 0o77 // Octal (Scala 3)
val binary = 0b1010 // Binary (Scala 3)
val long = 123L // Long typeFloating-point Literals
val double1 = 3.14
val double2 = 1.23e-4 // Scientific notation
val float = 3.14f // Float type
val double3 = 3.14d // Explicit Double typeCharacter Literals
val char1 = 'A'
val char2 = '\n' // Newline character
val char3 = '\u0041' // Unicode character 'A'String Literals
// Regular string
val str1 = "Hello, World!"
// String with escape characters
val str2 = "Line 1\nLine 2\tTabbed"
// Raw string (triple quotes)
val str3 = """This is a
|multi-line
|string""".stripMargin
// String interpolation
val name = "Alice"
val age = 25
val str4 = s"Name: $name, Age: $age"
val str5 = s"Next year: ${age + 1}"
// Formatted string
val str6 = f"Pi is approximately ${math.Pi}%.2f"
// Raw string interpolation
val path = raw"C:\Users\$name\Documents"Boolean Literals
val isTrue = true
val isFalse = falseSymbol Literals
val symbol1 = Symbol("name")
val symbol2 = 'name // Shorthand form (deprecated)Operators
Arithmetic Operators
val a = 10
val b = 3
val sum = a + b // 13
val diff = a - b // 7
val product = a * b // 30
val quotient = a / b // 3
val remainder = a % b // 1Relational Operators
val x = 5
val y = 10
val equal = x == y // false
val notEqual = x != y // true
val less = x < y // true
val greater = x > y // false
val lessEqual = x <= y // true
val greaterEqual = x >= y // falseLogical Operators
val p = true
val q = false
val and = p && q // false
val or = p || q // true
val not = !p // falseBitwise Operators
val a = 12 // 1100 in binary
val b = 10 // 1010 in binary
val bitwiseAnd = a & b // 8 (1000)
val bitwiseOr = a | b // 14 (1110)
val bitwiseXor = a ^ b // 6 (0110)
val bitwiseNot = ~a // -13
val leftShift = a << 1 // 24
val rightShift = a >> 1 // 6Assignment Operators
var x = 10
x += 5 // x = x + 5, result is 15
x -= 3 // x = x - 3, result is 12
x *= 2 // x = x * 2, result is 24
x /= 4 // x = x / 4, result is 6
x %= 4 // x = x % 4, result is 2Expressions and Statements
Expressions
In Scala, almost everything is an expression (has a return value):
// Simple expression
val result1 = 2 + 3 // 5
// Conditional expression
val result2 = if (x > 0) "positive" else "non-positive"
// Block expression
val result3 = {
val a = 10
val b = 20
a + b // Last expression in block is the return value
}
// Method call expression
val result4 = "hello".toUpperCase()Statements vs Expressions
// Expressions (have return values)
val x = 42 // Returns Unit
val y = if (x > 0) 1 else 0 // Returns Int
// Statements (mainly for side effects)
println("Hello") // Returns Unit
var counter = 0
counter += 1 // Returns UnitCode Blocks and Scope
Code Blocks
val result = {
val x = 10
val y = 20
val z = x + y
z * 2 // Block's return value
} // result = 60Scope Rules
val outer = "outer"
def example(): Unit = {
val inner = "inner"
{
val nested = "nested"
println(outer) // Can access
println(inner) // Can access
println(nested) // Can access
}
// println(nested) // Error: nested is out of scope
}Method Definition Syntax
Basic Method Definition
// With parameters and return type
def add(x: Int, y: Int): Int = {
x + y
}
// Simplified form (single expression)
def multiply(x: Int, y: Int): Int = x * y
// No parameter method
def getCurrentTime(): Long = System.currentTimeMillis()
// No parameter method (parentheses can be omitted)
def pi: Double = 3.14159Method Parameters
// Default parameters
def greet(name: String, greeting: String = "Hello"): String = {
s"$greeting, $name!"
}
// Named parameter calls
val message1 = greet("Alice")
val message2 = greet("Bob", "Hi")
val message3 = greet(greeting = "Hey", name = "Charlie")
// Variable parameters
def sum(numbers: Int*): Int = {
numbers.sum
}
val total = sum(1, 2, 3, 4, 5)Type Annotations
Variable Type Annotations
// Explicit type annotation
val name: String = "Alice"
val age: Int = 25
val height: Double = 5.6
// Type inference (recommended)
val name2 = "Bob" // Inferred as String
val age2 = 30 // Inferred as Int
val height2 = 5.8 // Inferred as DoubleMethod Type Annotations
// Return type annotation
def calculate(x: Int, y: Int): Int = x + y
// Complex type annotation
def processData(data: List[String]): Map[String, Int] = {
data.groupBy(identity).view.mapValues(_.length).toMap
}Import Statements
Basic Imports
import scala.collection.mutable.ListBuffer
import java.util.Date
import java.io.{File, FileReader} // Import multiple classesWildcard Imports
import scala.collection.mutable._ // Import everything in package
import java.util.{Date, Calendar, _} // Import specified classes and everything elseRenaming Imports
import java.util.{Date => JavaDate}
import scala.collection.mutable.{Map => MutableMap}
val now = new JavaDate()
val map = MutableMap[String, Int]()Hiding Imports
import java.util.{Date => _, _} // Import everything except DateRelative Imports
package com.example.app
import model._ // Import com.example.app.model package
import util.StringUtils // Import com.example.app.util.StringUtilsPackage Declarations
Basic Package Declaration
package com.example.myapp
class MyClass {
// Class definition
}Nested Packages
package com.example {
package myapp {
class MyClass
}
package utils {
class Helper
}
}Package Objects
package object myapp {
val VERSION = "1.0.0"
def utility(): String = "helper function"
}
// Can be used directly within package
package myapp
class MyClass {
println(VERSION) // Direct access to package object members
}Exercises
Exercise 1: Basic Syntax
Create a program containing the following:
// 1. Define a calculator object
object Calculator {
// 2. Define basic operation methods
def add(a: Double, b: Double): Double = a + b
def subtract(a: Double, b: Double): Double = a - b
def multiply(a: Double, b: Double): Double = a * b
def divide(a: Double, b: Double): Double = {
if (b != 0) a / b
else throw new IllegalArgumentException("Division by zero")
}
// 3. Main method
def main(args: Array[String]): Unit = {
val x = 10.0
val y = 3.0
println(s"$x + $y = ${add(x, y)}")
println(s"$x - $y = ${subtract(x, y)}")
println(s"$x * $y = ${multiply(x, y)}")
println(s"$x / $y = ${divide(x, y)}")
}
}Exercise 2: String Processing
object StringProcessor {
def processText(text: String): Unit = {
// Use string interpolation
println(s"Original: $text")
println(s"Length: ${text.length}")
println(s"Uppercase: ${text.toUpperCase}")
println(s"Lowercase: ${text.toLowerCase}")
// Use raw strings
val pattern = raw"\d+"
println(s"Pattern: $pattern")
// Use formatted strings
val percentage = 0.856
println(f"Percentage: ${percentage * 100}%.2f%%")
}
def main(args: Array[String]): Unit = {
processText("Hello, Scala World!")
}
}Summary
This chapter introduced Scala's basic syntax, including:
- Program Structure: Package declarations, imports, class/object definitions
- Comments: Single-line, multi-line, documentation comments
- Identifiers: Naming rules and conventions
- Literals: Literal representations of various data types
- Operators: Arithmetic, relational, logical, bitwise operators
- Expressions: Scala's expression-oriented feature
- Method Definitions: Basic syntax and parameter handling
- Type System: Type annotations and inference
- Imports and Packages: Organizing code modularly
Mastering these basic syntax rules is an important foundation for learning Scala. In the next chapter, we will dive deep into Scala Data Types to understand Scala's rich type system.