Scala 是一门多范式编程语言,它在同一个语言中融合了面向对象编程 (OOP) 和函数式编程 (FP) 的强大特性。它运行在 Java 虚拟机 (JVM) 上,能够充分利用 Java 庞大而成熟的生态系统。Scala 的设计宗旨是“可伸缩的语言 (Scalable Language)”,旨在优雅地处理从小型脚本到大型分布式系统等各种复杂的编程任务。本文件将重点介绍 Scala 的基本语法。
核心思想:理解 Scala 作为一种静态类型语言,其简洁的语法如何通过类型推断、强大的表达式和对不可变性的偏向,来提供富有表现力且健壮的代码。
一、程序入口:Hello World 任何编程语言的学习都从 “Hello World” 开始。在 Scala 中,一个可执行的程序通常通过一个 object(伴生对象或独立对象)定义一个 main 方法来启动。
1 2 3 4 5 6 object HelloWorld { def main (args: Array [String ]): Unit = { println("Hello, Scala World!" ) } }
object 关键字定义了一个单例对象。这意味着 HelloWorld 对象只有一个实例,它在程序首次访问时被创建。
def 关键字用于定义函数(或方法)。
main 是程序的入口函数,类似于 Java。它接受一个 Array[String] 类型的参数 args(用于接收命令行参数)。
: Unit 表示 main 函数没有返回值。Unit 类似于 Java 中的 void。
println 是 Scala 标准库中的一个函数,用于将字符串打印到标准输出。
运行方式 :
保存为 HelloWorld.scala。
编译:scalac HelloWorld.scala
运行:scala HelloWorld
二、变量与常量 Scala 区分为 val(常量/不可变变量)和 var(变量/可变变量)。Scala 强烈建议优先使用 val 来提高代码的可预测性和并发安全性。
val (Value) :用于定义常量或不可变引用。一旦赋值,其值就不能再改变。
var (Variable) :用于定义变量或可变引用。其值在声明后可以被重新赋值。
类型推断 :Scala 编译器通常能够根据初始值推断出变量的类型,因此显式地声明类型是可选的,但对于清晰性有时会有帮助。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 val message = "Hello Scala!" println(message) var count: Int = 0 println(count) count = 10 println(count) val pi = 3.14159 var isActive = true
三、基本数据类型 Scala 的数据类型都是对象,即使是基本类型(如 Int, Double),在底层它们也可以映射到 Java 的原生类型以优化性能。
数值类型 :Byte, Short, Int, Long, Float, Double
布尔类型 :Boolean (true/false)
字符类型 :Char
字符串类型 :String (本质上是 java.lang.String)
无返回值类型 :Unit (类似于 Java 的 void)
无值类型 :Null (类型层次结构的底部类型,可以赋值给任何引用类型)
所有类型之父 :Any (所有 Scala 类型的根基类)
1 2 3 4 5 6 val myInt: Int = 42 val myDouble: Double = 3.14 val myChar: Char = 'A 'val myBoolean: Boolean = true val myString: String = "Scala Programming" val nothing: Unit = ()
四、函数 函数是 Scala 的核心构建块,在 Scala 中,函数是“一等公民”,这意味着函数可以像任何其他值一样被传递、存储和操作(如赋值给变量、作为参数传递给其他函数、作为函数的返回值)。
4.1 函数定义 使用 def 关键字定义函数。函数可以有参数,也可以有返回值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 def add (x: Int , y: Int ): Int = { return x + y } def subtract (x: Int , y: Int ): Int = x - ydef greeting (): String = "Hello Scala Functions!" def printMessage (msg: String ): Unit = { println(msg) } println(add(5 , 3 )) println(subtract(10 , 4 )) println(greeting()) printMessage("This is a message." ) ### 4.2 匿名函数 (Lambda 表达式) 匿名函数是没有名称的函数。它们常被用作高阶函数的参数。 ```scala val increase = (x: Int ) => x + 1 println(increase(5 )) val numbers = List (1 , 2 , 3 , 4 , 5 ) val doubledNumbers = numbers.map((x: Int ) => x * 2 ) println(doubledNumbers) val tripledNumbers = numbers.map(_ * 3 )println(tripledNumbers)
五、控制结构 Scala 的控制结构通常是“表达式 (Expressions)”,这意味着它们会返回一个值,这与许多其他语言中控制结构是“语句 (Statements)”不同。
5.1 If/Else 表达式 if/else 结构在 Scala 中是一个表达式,它会返回一个值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 val x = 10 val y = 20 val max = if (x > y) x else y println(s"The maximum is $max " ) val result = if (x < 0 ) { "Negative" } else if (x == 0 ) { "Zero" } else { "Positive" } println(result)
5.2 循环 Scala 提供了 while 和 do-while 循环,但更推荐使用 for 表达式,尤其是用于集合遍历。
While 循环 1 2 3 4 5 var i = 0 while (i < 5 ) { println(s"While loop count: $i " ) i += 1 }
For 表达式 (For Comprehensions) for 表达式是 Scala 中处理集合和生成新集合的强大工具。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 for (i <- 1 to 3 ) { println(s"For loop count (to): $i " ) } for (i <- 1 until 3 ) { println(s"For loop count (until): $i " ) } val fruits = List ("apple" , "banana" , "cherry" )for (fruit <- fruits) { println(s"Fruit: $fruit " ) } for (num <- 1 to 10 if num % 2 == 0 ) { println(s"Even number: $num " ) } val doubledList = for (num <- numbers) yield num * 2 println(s"Doubled list: $doubledList " )
5.3 Match 表达式 (模式匹配) match 表达式是 Scala 中一个非常强大的控制流结构,它比传统的 switch 语句功能更丰富,支持匹配值、类型、序列结构、case class 实例等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 def describeValue (x: Any ): String = x match { case 0 => "Zero" case 1 => "One" case i: Int if i > 10 => s"Large integer: $i " case s: String => s"A string: '$s '" case List (0 , _*) => "A list starting with 0" case _ => "Something else" } println(describeValue(0 )) println(describeValue(5 )) println(describeValue(15 )) println(describeValue("hello" )) println(describeValue(List (0 , 1 , 2 ))) println(describeValue(true ))
六、类与对象 Scala 是一种纯粹的面向对象语言,所有的值都是对象。
6.1 类 (Classes) class 关键字用于定义一个新的类,它是创建对象的蓝图。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class GreeterClass { val message = "Hello from GreeterClass!" def sayHello (): Unit = { println(message) } } val greeter = new GreeterClass ()greeter.sayHello() class Person (val name: String , var age: Int ) { def describe (): Unit = { println(s"This person is $name and is $age years old." ) } } val alice = new Person ("Alice" , 30 ) alice.describe() println(alice.name) alice.age = 31 alice.describe()
6.2 伴生对象 (Companion Objects) 在 Scala 中,一个 class 可以拥有一个与它同名的 object,这个 object 被称为该 class 的伴生对象。伴生对象可以访问类的私有成员,常用于存放工厂方法、静态成员或工具方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Account (val id: String , private var balance: Double ) { def deposit (amount: Double ): Unit = { if (amount > 0 ) balance += amount } def getBalance : Double = balance } object Account { def createNewAccount (initialBalance: Double ): Account = { new Account (java.util.UUID .randomUUID().toString, initialBalance) } } val myAccount = Account .createNewAccount(100.0 ) println(s"New account ID: ${myAccount.id} , Balance: ${myAccount.getBalance} " ) myAccount.deposit(50.0 ) println(s"New balance: ${myAccount.getBalance} " )
6.3 Case Class (样例类) case class 是一种特殊(但特别常用)的类,它主要用于不可变数据的建模。编译器会自动为 case class 生成许多有用的方法,例如:
构造器参数自动提升为公共的 val 成员
equals 和 hashCode 方法 :基于内容而非引用进行比较
toString 方法 :提供漂亮的字符串表示
copy 方法 :用于创建副本,并可修改部分字段
apply 方法 :无需 new 关键字即可创建实例(在伴生对象中)
unapply 方法 :支持模式匹配
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 case class Book (title: String , author: String , year: Int )val book1 = Book ("The Hitchhiker's Guide to the Galaxy" , "Douglas Adams" , 1979 )val book2 = Book ("The Hitchhiker's Guide to the Galaxy" , "Douglas Adams" , 1979 )val book3 = Book ("Scala for the Impatient" , "Cay S. Horstmann" , 2012 )println(book1) println(book1 == book2) println(book1 == book3) val updatedBook = book1.copy(year = 1980 ) println(updatedBook) def getPublicationYear (item: Any ): String = item match { case Book (title, _, year) => s"$title was published in $year ." case _ => "Not a book." } println(getPublicationYear(book1))
七、集合字面量 Scala 提供了丰富且功能强大的集合库,默认的集合都是不可变的(immutable),这意味着一旦创建就不能修改。
7.1 List (列表) 有序、不可变的同类型元素序列。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 val emptyList: List [Int ] = List ()val numbersList = List (1 , 2 , 3 , 4 , 5 )val fruitsList = List ("apple" , "banana" , "orange" )println(numbersList(0 )) println(numbersList.head) println(numbersList.tail) println(numbersList.isEmpty) println(numbersList.length) println(numbersList.contains(3 )) val moreNumbers = List (6 , 7 )val combinedList = numbersList ::: moreNumbers println(combinedList) val squaredNumbers = numbersList.map(n => n * n)println(squaredNumbers)
7.2 Map (映射) 键值对的不可变集合。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 val emptyMap: Map [String , Int ] = Map ()val ages = Map ("Alice" -> 30 , "Bob" -> 25 , "Charlie" -> 35 )println(ages.get("Alice" )) println(ages.get("David" )) println(ages("Bob" )) println(ages.contains("Charlie" )) println(ages.keys) println(ages.values) for ((name, age) <- ages) { println(s"$name is $age years old." ) }
7.3 Set (集合) 不包含重复元素的不可变集合。
1 2 3 4 5 6 7 8 9 10 11 12 val emptySet: Set [Int ] = Set ()val uniqueNumbers = Set (1 , 2 , 3 , 2 , 4 ) println(uniqueNumbers) println(uniqueNumbers.contains(3 )) println(uniqueNumbers + 5 ) println(uniqueNumbers - 2 ) val otherSet = Set (3 , 4 , 5 )println(uniqueNumbers intersect otherSet) println(uniqueNumbers union otherSet)
八、注释 Scala 支持单行注释和多行注释。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 def exampleFunction (name: String ): String = { s"Hello, $name !" }
九、总结 本文件详细介绍了 Scala 的基本语法,包括程序入口、变量与常量、核心数据类型、函数的定义与使用、控制结构(if/else, for, match)、类与对象(普通类、伴生对象、样例类)以及常用的不可变集合(List, Map, Set)的字面量表示。掌握这些基础知识是深入学习 Scala 强大特性的基石。通过理解和实践这些基本语法,开发者可以开始构建简洁、健壮且富有表现力的 Scala 应用程序。