Scala 字面量(完整教程)

什么是 Scala 字面量?

在编程的世界里,字面量就像语言中的“实词”——它们是直接写出来的、不可再分解的值。比如你在写代码时写下的 42"Hello",这些就是字面量。它们不依赖变量、不经过计算,就是“原样出现”的数据。

在 Scala 中,字面量的表达方式非常直观,而且支持多种数据类型。理解它们,是掌握 Scala 的第一步。你可以把 Scala 字面量想象成一个“数据仓库”的入口,每个入口对应一种数据类型,比如整数、浮点数、字符串、布尔值等等。

更重要的是,Scala 字面量不仅仅是简单的数字或文字,它们还具备类型推断能力。当你写 val x = 100,Scala 会自动识别 100 是一个 Int 类型的字面量,而不需要你显式声明。这种“自动识别”机制,让代码更简洁,也更安全。

在接下来的内容中,我们会逐步拆解 Scala 中常见的字面量类型,从最基础的数字和字符串,到更高级的集合与元组,带你一步步建立起对 Scala 字面量的全面理解。


数字字面量:整数与浮点数

Scala 支持多种数字字面量,包括整数和浮点数。它们的写法和 Java 类似,但更灵活。

整数类型

Scala 中的整数字面量支持十进制、十六进制和二进制格式,这让你在处理底层数据时更加方便。

// 十进制整数(默认为 Int 类型)
val decimal = 123

// 十六进制整数,前缀为 0x
val hex = 0xFF  // 等于 255

// 二进制整数,前缀为 0b
val binary = 0b1010  // 等于 10

// 长整型,以 L 结尾
val longValue = 1234567890L

注释:0x 表示十六进制,0b 表示二进制。L 后缀用于明确指定 Long 类型,避免溢出。如果一个整数太大,Int 会溢出,所以用 L 可以防止这种错误。

浮点数类型

浮点数字面量支持 FloatDouble 两种类型,其中 Double 是默认类型。

// 双精度浮点数(默认类型)
val double = 3.14159

// 单精度浮点数,以 F 结尾
val float = 3.14F

// 科学计数法
val scientific = 1.23e-4  // 等于 0.000123

注释:e 表示科学计数法,1.23e-4 就是 1.23 × 10⁻⁴。F 后缀用于明确指定 Float 类型,避免精度损失。


字符与字符串字面量

字符串是程序中最常见的数据类型之一,Scala 的字符串字面量非常强大,支持多种写法。

基本字符串字面量

// 普通字符串,用双引号包裹
val greeting = "Hello, Scala!"

// 字符字面量,用单引号包裹
val letter = 'A'

注释:'A' 是一个 Char 类型的字面量,代表单个字符。字符串是 String 类型,字符是 Char 类型,两者不能混用。

多行字符串与原始字符串

Scala 提供了 """ 语法来定义多行字符串,这在处理 SQL、JSON 或 HTML 代码时特别有用。

// 多行字符串,保留换行和缩进
val multiLine = """
  |SELECT name, age
  |FROM users
  |WHERE age > 18
  """.stripMargin

// stripMargin 去除每行开头的竖线,保留实际内容

注释:stripMargin 是一个字符串方法,用于去除以 | 开头的缩进。| 可以当作“边框”,方便格式化代码块。

字符串插值

Scala 提供了强大的字符串插值功能,让你可以像拼接一样动态插入变量。

val name = "Alice"
val age = 25

// s-插值:支持变量和表达式
val message = s"Hello, $name! You are $age years old."

// f-插值:格式化输出,类似 printf
val formatted = f"Pi is approximately $3.14159%.4f"

// raw-插值:保留转义字符
val rawText = raw"Newline: \n and tab: \t"

注释:$name 会替换为变量值,$3.14159%.4f 表示保留 4 位小数。raw 插值不会处理 \n 这样的转义字符,适合处理原始文本。


布尔与空值字面量

布尔值是程序逻辑判断的基础。Scala 中,布尔字面量只有两个:truefalse

val isAlive = true
val hasPermission = false

注释:布尔字面量是 Boolean 类型的,用于条件判断。注意:Scala 中没有 10 表示真/假,必须用 true/false

空值字面量:null

虽然 Scala 推荐使用 Option 类型来处理可空值,但 null 字面量仍然存在。

val nothing = null  // 类型为 Null,通常与 AnyRef 混合使用

注释:null 是所有引用类型的默认值。但强烈建议避免使用 null,改用 Option[T](如 Some(value)None)来表示“可能为空”的情况。


集合字面量:数组、列表、映射与集合

Scala 的集合字面量语法简洁,是处理数据的核心工具。

创建数组与初始化

// 创建整数数组
val numbers = Array(1, 2, 3, 4, 5)

// 创建字符串数组
val names = Array("Alice", "Bob", "Charlie")

// 使用工厂方法创建空数组
val emptyArray = Array.empty[Int]

注释:Array 是可变数组,支持修改元素。Array.empty[T] 创建一个空数组,类型由 T 指定。

列表字面量

// 创建不可变列表
val fruits = List("apple", "banana", "orange")

// 空列表
val emptyList = List.empty[String]

注释:List 是不可变的,一旦创建就不能修改。适合用于函数式编程,避免副作用。

映射字面量

// 创建键值对映射(Map)
val ages = Map("Alice" -> 25, "Bob" -> 30, "Charlie" -> 35)

// 空映射
val emptyMap = Map.empty[String, Int]

注释:-> 是键值对的语法糖,等价于 Tuple2(key, value)Map 是不可变的,适合存储配置或数据映射。

集合字面量对比表

类型 可变性 语法示例 适用场景
Array 可变 Array(1, 2, 3) 需要频繁修改的数组
List 不可变 List("a", "b") 函数式编程、递归处理
Map 不可变 Map("k" -> "v") 键值映射、配置数据
Set 不可变 Set(1, 2, 3) 去重、集合运算

注释:Set 不允许重复元素,适合去重操作。MapSet 默认是不可变的,若需可变版本,可用 scala.collection.mutable.Map


元组与函数字面量

元组是 Scala 中一种轻量级的复合数据结构,适合返回多个值。

元组字面量

// 创建二元组
val pair = (1, "hello")

// 创建五元组
val info = (100, "Alice", 25, true, 3.14)

// 访问元组元素(从 1 开始)
val first = pair._1  // 1
val second = pair._2 // "hello"

注释:元组的元素通过 _1, _2 等方式访问,索引从 1 开始。元组适合临时返回多个值,比如 getUserInfo() 返回 (id, name, age)

函数字面量

函数字面量是 Scala 中最强大的特性之一,它允许你直接写出一个函数。

// 定义一个函数字面量:接收 Int,返回 Int
val square = (x: Int) => x * x

// 调用函数
val result = square(5)  // 25

// 多参数函数
val add = (a: Int, b: Int) => a + b

// 无参数函数
val greet = () => "Hello!"

注释:=> 是函数字面量的语法,左边是参数列表,右边是函数体。函数字面量可以作为变量赋值,也可以作为参数传入其他函数。


总结:Scala 字面量的实用价值

通过本文,你已经掌握了 Scala 中各种常见字面量的用法。从数字到字符串,从布尔值到集合,每一种字面量都在特定场景中发挥着不可替代的作用。

Scala 字面量之所以强大,不仅在于语法简洁,更在于它与类型系统无缝结合。当你写 100 时,Scala 会自动推断它是 Int;当你写 Map("a" -> 1) 时,它会自动识别为 Map[String, Int]。这种“自动推断”能力,让代码更清晰,也更安全。

更重要的是,Scala 字面量是构建函数式编程的基础。你可以在一行代码中创建一个函数、一个列表、一个元组,然后直接传递给高阶函数。这种“表达即逻辑”的风格,正是 Scala 的魅力所在。

所以,如果你刚开始接触 Scala,别急着学复杂的语法。先从字面量开始,把它们当成你编程的“积木”。当你能熟练拼出数字、字符串、列表和函数,你就已经走在了掌握 Scala 的正确路上。