Biểu thức, giá trị, biến và khối mã
Trong Scala, mọi thứ gần như đều là biểu thức. Ví dụ:
val result = 2 + 3
println(result) // In ra 5
Dữ liệu bất biến được khai báo bằng từ khóa val. Một khi đã gán giá trị, bạn không thể thay đổi nó.
val x: Int = 5
// x = 10 // Lỗi biên dịch
Ngược lại, dữ liệu có thể thay đổi dùng var:
var counter = 0
counter = counter + 1
Một khối mã (code block) nằm trong dấu ngoặc nhọn {}, và giá trị của khối là kết quả của biểu thức cuối cùng:
println({
val a = 10
val b = 20
a * b
}) // In ra 200
Hàm và phương thức
Hàm ẩn danh (lambda) được định nghĩa dễ dàng:
val square = (n: Int) => n * n
println(square(4)) // 16
Hàm có thể nhận nhiều tham số hoặc không nhận gì cả:
val multiply = (a: Int, b: Int) => a * b
val greet = () => println("Xin chào!")
Phương thức được định nghĩa bằng def, thường nằm bên trong lớp hoặc đối tượng:
def add(a: Int, b: Int): Int = a + b
Scala hỗ trợ kỹ thuật currification – chia một hàm thành nhiều danh sách tham số:
def sumAndScale(a: Int, b: Int)(factor: Int): Int = (a + b) * factor
println(sumAndScale(2, 3)(4)) // 20
Một phương thức cũng có thể không trả về giá trị cụ thể (tương đương void), dùng kiểu Unit:
def log(message: String): Unit = println(s"[LOG] $message")
Lớp và lớp mẫu (case class)
Lớp thông thường được khai báo bằng class và khởi tạo bằng new:
class Person(val name: String, val age: Int)
val person = new Person("Alice", 30)
Tuy nhiên, với case class, việc khởi tạo đơn giản hơn vì không cần từ khóa new, đồng thời tự động hỗ trợ so sánh theo giá trị:
case class Vector2D(x: Double, y: Double)
val v1 = Vector2D(1.0, 2.0)
val v2 = Vector2D(1.0, 2.0)
println(v1 == v2) // true
Đối tượng đơn thể (Singleton Object)
Scala không có phương thức static, thay vào đó dùng object để tạo ra một thể hiện duy nhất:
object Counter {
private var value = 0
def increment(): Unit = value += 1
def current(): Int = value
}
Counter.increment()
println(Counter.current()) // 1
Đặc điểm (Trait)
Trait giống như interface trong Java nhưng mạnh hơn vì có thể chứa cài đặt mặc định:
trait Speaker {
def speak(): Unit = println("Tôi đang nói")
}
class Dog extends Speaker {
override def speak(): Unit = println("Gâu gâu!")
}
val dog = new Dog
dog.speak() // Gâu gâu!
Một lớp có thể kế thừa nhiều trait thông qua with.
Phương thức chính (Main Method)
Điểm bắt đầu chương trình nằm trong object có phương thức main:
object MyApp {
def main(args: Array[String]): Unit = {
println("Chương trình bắt đầu!")
}
}
Hệ thống kiểu trong Scala
Scala có hệ thống kiểu phân cấp rõ ràng:
- Any: Siêu lớp của mọi kiểu dữ liệu.
- AnyVal: Các kiểu giá trị nguyên thủy như
Int,Double,Boolean, v.v. - AnyRef: Tương đương với
Objecttrong Java, bao gồm tất cả lớp do người dùng định nghĩa. - Nothing: Tiểu lớp của mọi kiểu, dùng để biểu diễn giá trị không tồn tại (ví dụ: ném ngoại lệ).
Bạn có thể tạo danh sách chứa nhiều kiểu khác nhau nhờ tính kế thừa từ Any:
val mixedList: List[Any] = List("Chuỗi", 123, true, 3.14, List(1, 2))
mixedList.foreach(println)