Scala 编程学习笔记

1. 变量与常量

Scala 中 val 声明不可变变量,var 声明可变变量。

val age = 30  // 不可更改
var name = "Alice"  // 可更改

注意事项: val 是不可变的,适用于大部分场景,减少错误。

2. 数据类型

Scala 是强类型语言,常用数据类型包括 IntDoubleStringBoolean 等。

val height: Double = 1.75
val isStudent: Boolean = true

易错点:类型推断通常可省略类型定义,但在复杂结构中可能需要显式声明。

3. 条件语句

Scala 使用 ifelse 语句进行条件判断,语句返回值可赋值给变量。

val status = if (age > 18) "Adult" else "Minor"

注意事项:条件表达式必须返回相同类型的值。

4. 函数

使用 def 定义函数,Scala 支持单表达式函数。

def greet(name: String): String = s"Hello, $name!"

易错点:在不返回值的函数中可以省略返回类型,否则应显式声明。

5. 类与对象

Scala 类的定义较为简洁,伴生对象用 object 定义静态成员。

class Person(val name: String, var age: Int)
object Person {
    def apply(name: String, age: Int) = new Person(name, age)
}

注意事项:使用伴生对象的 apply 方法可以更方便地创建类实例。

6. 模式匹配

Scala 提供强大的模式匹配功能,通过 match 进行模式匹配。

val number = 2
val result = number match {
    case 1 => "One"
    case 2 => "Two"
    case _ => "Other"
}

易错点:在模式匹配时需考虑所有可能性,使用 _ 作为通配符匹配所有其他情况。

7. 集合操作

Scala 提供丰富的集合操作方法,如 mapfilterreduce

val numbers = List(1, 2, 3, 4)
val doubled = numbers.map(_ * 2)   // 结果: List(2, 4, 6, 8)

注意事项:集合操作返回新的集合,原集合不变,避免意外修改。

8. 泛型

Scala 支持泛型,允许在类和函数中使用类型参数。

class Box[T](val content: T)

注意事项:泛型在类型推断时可能需要显式指定,特别是在复杂嵌套结构中。

9. 高阶函数

Scala 支持高阶函数,可以将函数作为参数传递或作为返回值。

def applyFunc(f: Int => Int, x: Int): Int = f(x)
applyFunc(_ * 2, 5)  // 结果: 10

易错点:传递匿名函数时,注意使用占位符符号 _ 替代参数。

10. 隐式转换

Scala 支持隐式转换,允许在不匹配的类型间自动转换。

implicit def intToString(x: Int): String = x.toString
val str: String = 123  // 自动转换为字符串 "123"

注意事项:滥用隐式转换会导致代码难以维护,应避免过度使用。

11. 并发编程

Scala 使用 Future 实现并发编程,通过回调处理结果。

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global

val f: Future[Int] = Future {
    Thread.sleep(1000)
    42
}
f.onComplete {
    case Success(value) => println(s"Result: $value")
    case Failure(e) => println(s"Error: $e")
}

注意事项:Scala 中的并发依赖于正确的线程上下文 ExecutionContext

高级与小众用法

case 类

case 类用于不可变的数据对象,带有模式匹配支持。

case class Person(name: String, age: Int)

注意事项:case 类自动提供 copy 方法和不可变性。

柯里化函数

Scala 支持柯里化,将多个参数分成多个参数列表。

def add(x: Int)(y: Int): Int = x + y
val addFive = add(5) _

易错点:柯里化函数调用时需保留占位符 _ 表示部分应用。

部分函数应用

部分函数应用允许固定部分参数,返回新的函数。

def add(a: Int, b: Int, c: Int): Int = a + b + c
val addWithFive = add(5, _: Int, _: Int)

注意事项:使用 _ 符号代表未固定的参数位置。

尾递归

Scala 优化尾递归以避免栈溢出,需要在递归函数上使用 @tailrec 注解。

import scala.annotation.tailrec
@tailrec
def factorial(n: Int, acc: Int = 1): Int = {
    if (n <= 1) acc
    else factorial(n - 1, acc * n)
}

易错点:确保递归函数为尾递归,否则会导致栈溢出错误。

for 推导式

Scala 的 for 推导式可以生成新的集合。

val numbers = List(1, 2, 3)
val doubled = for (n <- numbers) yield n * 2

注意事项:yield 关键字用于返回新集合,避免修改原集合。

类型类和上下文绑定

类型类是一种多态实现方式,使用上下文绑定 : 限制类型参数。

trait Show[A] {
    def show(a: A): String
}

implicit object ShowInt extends Show[Int] {
    def show(a: Int): String = s"Int: $a"
}

def printValue[A: Show](value: A): Unit = {
    val instance = implicitly[Show[A]]
    println(instance.show(value))
}

易错点:上下文绑定要求存在符合类型的隐式对象实例。