Scala 字面量
字面量是在源代码中直接表示值的符号。本章将详细介绍 Scala 中各种类型的字面量表示方法。
整数字面量
十进制字面量
scala
val decimal1 = 0 // Int
val decimal2 = 123 // Int
val decimal3 = 456789 // Int
// 使用下划线分隔提高可读性(Scala 2.13+)
val largeNumber = 1_000_000 // 1000000
val creditCard = 1234_5678_9012_3456L十六进制字面量
scala
val hex1 = 0x0 // 0
val hex2 = 0xFF // 255
val hex3 = 0xCAFEBABE // 3405691582
val hex4 = 0x7FFFFFFF // Int.MaxValue
// 大小写不敏感
val hexLower = 0xcafebabe
val hexUpper = 0xCAFEBABE
val hexMixed = 0xCafeBabe八进制字面量(Scala 3)
scala
// Scala 3 支持八进制字面量
val octal1 = 0o777 // 511
val octal2 = 0o123 // 83
val octal3 = 0o0 // 0
// 注意:Scala 2 不支持 0o 前缀的八进制二进制字面量(Scala 3)
scala
// Scala 3 支持二进制字面量
val binary1 = 0b1010 // 10
val binary2 = 0b1111 // 15
val binary3 = 0b0 // 0
val binary4 = 0b11111111 // 255
// 使用下划线分隔
val binaryLarge = 0b1111_0000_1010_1010长整型字面量
scala
val long1 = 123L // Long 类型
val long2 = 456l // Long 类型(小写 l,不推荐)
val longHex = 0xFFFFFFFFL
val longMax = 9223372036854775807L // Long.MaxValue
// 大数字使用下划线分隔
val longLarge = 123_456_789_012_345L浮点数字面量
Double 字面量
scala
val double1 = 3.14 // Double
val double2 = 0.0 // Double
val double3 = 1. // 1.0 (Double)
val double4 = .5 // 0.5 (Double)
// 科学计数法
val scientific1 = 1.23e4 // 12300.0
val scientific2 = 1.23E4 // 12300.0
val scientific3 = 1.23e-4 // 0.000123
val scientific4 = 1.23E-4 // 0.000123
// 显式 Double 后缀
val explicitDouble = 3.14d // Double
val explicitDouble2 = 3.14D // DoubleFloat 字面量
scala
val float1 = 3.14f // Float
val float2 = 3.14F // Float
val float3 = 0.0f // Float
// 科学计数法的 Float
val floatScientific = 1.23e4f // 12300.0f
val floatScientific2 = 1.23E-4F // 0.000123f
// Float 的特殊值
val floatInfinity = Float.PositiveInfinity
val floatNegInfinity = Float.NegativeInfinity
val floatNaN = Float.NaN特殊浮点值
scala
// 正无穷大
val posInf = Double.PositiveInfinity
val posInfFloat = Float.PositiveInfinity
// 负无穷大
val negInf = Double.NegativeInfinity
val negInfFloat = Float.NegativeInfinity
// 非数字 (Not a Number)
val nan = Double.NaN
val nanFloat = Float.NaN
// 检查特殊值
val isInfinite = posInf.isInfinite // true
val isNaN = nan.isNaN // true
val isFinite = 3.14.isFinite // true字符字面量
基本字符字面量
scala
val char1 = 'A' // 字符 A
val char2 = 'z' // 字符 z
val char3 = '0' // 字符 0
val char4 = ' ' // 空格字符
val char5 = '中' // 中文字符转义字符字面量
scala
val tab = '\t' // 制表符
val newline = '\n' // 换行符
val carriageReturn = '\r' // 回车符
val backslash = '\\' // 反斜杠
val singleQuote = '\'' // 单引号
val doubleQuote = '\"' // 双引号
val backspace = '\b' // 退格符
val formFeed = '\f' // 换页符Unicode 字符字面量
scala
val unicodeA = '\u0041' // 'A' (Unicode)
val unicodeHeart = '\u2764' // ❤ (心形符号)
val unicodeSmiley = '\u263A' // ☺ (笑脸)
val unicodeChinese = '\u4E2D' // 中
// 打印 Unicode 字符
println(s"Heart: $unicodeHeart")
println(s"Smiley: $unicodeSmiley")
println(s"Chinese: $unicodeChinese")八进制字符字面量
scala
val octalChar1 = '\101' // 'A' (八进制 101 = 十进制 65)
val octalChar2 = '\141' // 'a' (八进制 141 = 十进制 97)
val octalChar3 = '\0' // null 字符字符串字面量
普通字符串字面量
scala
val str1 = "Hello, World!"
val str2 = "Scala is awesome"
val str3 = "" // 空字符串
val str4 = "包含中文的字符串"
// 包含转义字符的字符串
val escaped = "Line 1\nLine 2\tTabbed text"
val quoted = "He said \"Hello\" to me"
val path = "C:\\Users\\username\\Documents"原始字符串字面量
使用三重双引号创建原始字符串,不需要转义:
scala
val rawString = """This is a raw string.
It can contain "quotes" and \backslashes
without escaping them."""
val sqlQuery = """
SELECT name, age, email
FROM users
WHERE age > 18
AND active = true
ORDER BY name
"""
val regexPattern = """^\d{3}-\d{2}-\d{4}$""" // 正则表达式
// 使用 stripMargin 处理缩进
val formattedString = """
|This is line 1
|This is line 2
|This is line 3
""".stripMargin
// 自定义边界字符
val customMargin = """
#This uses # as margin
#Instead of |
#Very flexible
""".stripMargin('#')字符串插值字面量
s 插值器
scala
val name = "Alice"
val age = 25
val height = 5.6
// 基本插值
val basic = s"Name: $name, Age: $age"
// 表达式插值
val expression = s"Next year $name will be ${age + 1} years old"
val calculation = s"Area: ${math.Pi * 2 * 2}"
// 方法调用插值
val upper = s"Uppercase name: ${name.toUpperCase}"f 插值器(格式化)
scala
val pi = math.Pi
val e = math.E
// 浮点数格式化
val formatted1 = f"Pi: $pi%.2f" // "Pi: 3.14"
val formatted2 = f"E: $e%.4f" // "E: 2.7183"
// 整数格式化
val number = 42
val formatted3 = f"Number: $number%05d" // "Number: 00042"
// 字符串格式化
val text = "hello"
val formatted4 = f"Text: $text%10s" // "Text: hello"
val formatted5 = f"Text: $text%-10s" // "Text: hello "raw 插值器
scala
val path = raw"C:\Users\$name\Documents"
// 结果: "C:\Users\Alice\Documents" (反斜杠不被转义)
val regex = raw"\d+\.\d+" // 正则表达式,不需要双重转义
val windowsPath = raw"D:\Projects\Scala\src\main\scala"自定义插值器
scala
// 定义自定义插值器
implicit class JsonInterpolator(val sc: StringContext) extends AnyVal {
def json(args: Any*): String = {
val strings = sc.parts.iterator
val expressions = args.iterator
val buf = new StringBuilder(strings.next())
while (strings.hasNext) {
buf.append(expressions.next())
buf.append(strings.next())
}
buf.toString
}
}
// 使用自定义插值器
val key = "name"
val value = "Alice"
val jsonString = json"""{"$key": "$value"}"""
// 结果: """{"name": "Alice"}"""布尔字面量
scala
val isTrue = true // Boolean true
val isFalse = false // Boolean false
// 布尔运算
val and = true && false // false
val or = true || false // true
val not = !true // false
// 在条件表达式中使用
val result = if (isTrue) "yes" else "no"
val status = if (isFalse) "inactive" else "active"符号字面量
符号是不可变的字符串,通常用作标识符:
scala
val symbol1 = Symbol("name") // 完整形式
val symbol2 = 'name // 简写形式(已弃用)
// 符号的使用
val symbols = Map(
Symbol("firstName") -> "Alice",
Symbol("lastName") -> "Smith",
Symbol("age") -> 25
)
val firstName = symbols(Symbol("firstName"))数组字面量
scala
// 数组字面量
val intArray = Array(1, 2, 3, 4, 5)
val stringArray = Array("a", "b", "c")
val mixedArray = Array(1, "hello", true, 3.14)
// 空数组
val emptyIntArray = Array.empty[Int]
val emptyStringArray = Array[String]()
// 指定大小的数组
val zeroArray = Array.fill(5)(0) // Array(0, 0, 0, 0, 0)
val rangeArray = Array.range(1, 6) // Array(1, 2, 3, 4, 5)集合字面量
List 字面量
scala
val list1 = List(1, 2, 3, 4, 5)
val list2 = List("a", "b", "c")
val emptyList = List()
val nilList = Nil
// 使用 cons 操作符
val consList = 1 :: 2 :: 3 :: Nil // List(1, 2, 3)
val prependList = 0 :: list1 // List(0, 1, 2, 3, 4, 5)Set 字面量
scala
val set1 = Set(1, 2, 3, 2, 1) // Set(1, 2, 3) - 去重
val set2 = Set("apple", "banana", "cherry")
val emptySet = Set.empty[String]Map 字面量
scala
val map1 = Map("a" -> 1, "b" -> 2, "c" -> 3)
val map2 = Map(1 -> "one", 2 -> "two", 3 -> "three")
val emptyMap = Map.empty[String, Int]
// 使用元组语法
val map3 = Map(("x", 10), ("y", 20), ("z", 30))Vector 字面量
scala
val vector1 = Vector(1, 2, 3, 4, 5)
val vector2 = Vector("hello", "world")
val emptyVector = Vector.empty[Double]元组字面量
scala
val tuple2 = (1, "hello") // Tuple2[Int, String]
val tuple3 = (1, "hello", true) // Tuple3[Int, String, Boolean]
val tuple4 = (1, 2.0, "three", false) // Tuple4[Int, Double, String, Boolean]
// 嵌套元组
val nested = ((1, 2), ("a", "b")) // ((Int, Int), (String, String))
// 单元素元组(需要逗号)
val singleTuple = (42,) // Tuple1[Int]函数字面量
scala
// 匿名函数字面量
val add = (x: Int, y: Int) => x + y
val square = (x: Int) => x * x
val isEven = (x: Int) => x % 2 == 0
// 简化语法
val double = (_: Int) * 2
val increment = (_: Int) + 1
// 多参数简化
val sum = (_: Int) + (_: Int)
// 无参数函数
val random = () => scala.util.Random.nextInt(100)正则表达式字面量
scala
// 使用 r 方法创建正则表达式
val emailRegex = """[\w\.-]+@[\w\.-]+\.\w+""".r
val phoneRegex = """\d{3}-\d{3}-\d{4}""".r
val dateRegex = """\d{4}-\d{2}-\d{2}""".r
// 使用正则表达式
val email = "user@example.com"
val isValidEmail = emailRegex.matches(email)
val text = "Call me at 123-456-7890"
val phoneNumbers = phoneRegex.findAllIn(text).toList特殊字面量
Unit 字面量
scala
val unit1 = () // Unit 类型的唯一值
val unit2: Unit = {} // 空代码块也返回 Unit
def sideEffect(): Unit = {
println("This has side effects")
() // 显式返回 Unit
}Null 字面量
scala
val nullValue: String = null // 不推荐使用
val nullList: List[Int] = null // 不推荐使用
// 推荐使用 Option 代替 null
val optionalValue: Option[String] = None
val someValue: Option[String] = Some("hello")实际应用示例
配置文件解析
scala
object ConfigParser {
// 使用各种字面量定义配置
val defaultConfig = Map(
"server.port" -> 8080,
"server.host" -> "localhost",
"database.url" -> "jdbc:postgresql://localhost:5432/mydb",
"database.username" -> "user",
"database.password" -> "password",
"app.debug" -> true,
"app.version" -> "1.0.0",
"app.timeout" -> 30.0
)
// 使用原始字符串定义 SQL
val createUserTable = """
|CREATE TABLE users (
| id SERIAL PRIMARY KEY,
| name VARCHAR(100) NOT NULL,
| email VARCHAR(255) UNIQUE NOT NULL,
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|)
""".stripMargin
// 使用字符串插值生成动态 SQL
def findUserByEmail(email: String): String = {
s"""
|SELECT id, name, email, created_at
|FROM users
|WHERE email = '$email'
""".stripMargin
}
}数据验证
scala
object Validators {
// 正则表达式字面量
val emailRegex = """^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$""".r
val phoneRegex = """^\+?1?[-.\s]?\(?(\d{3})\)?[-.\s]?(\d{3})[-.\s]?(\d{4})$""".r
val zipCodeRegex = """^\d{5}(-\d{4})?$""".r
// 验证函数
def validateEmail(email: String): Boolean = {
emailRegex.matches(email)
}
def validatePhone(phone: String): Boolean = {
phoneRegex.matches(phone)
}
def validateZipCode(zip: String): Boolean = {
zipCodeRegex.matches(zip)
}
// 测试数据
val testEmails = List(
"user@example.com",
"invalid.email",
"test@domain.co.uk"
)
val testPhones = List(
"123-456-7890",
"(123) 456-7890",
"1234567890"
)
}练习
练习 1:字面量识别
scala
object LiteralExercise {
// 识别以下字面量的类型
val mystery1 = 42 // Int
val mystery2 = 42L // Long
val mystery3 = 3.14f // Float
val mystery4 = 3.14 // Double
val mystery5 = 'A' // Char
val mystery6 = "Hello" // String
val mystery7 = true // Boolean
val mystery8 = () // Unit
val mystery9 = 0xFF // Int (255)
val mystery10 = 1.23e-4 // Double
def printTypes(): Unit = {
println(s"mystery1: ${mystery1.getClass.getSimpleName}")
println(s"mystery2: ${mystery2.getClass.getSimpleName}")
println(s"mystery3: ${mystery3.getClass.getSimpleName}")
// ... 继续打印其他类型
}
}练习 2:字符串插值应用
scala
object StringInterpolationExercise {
case class Product(name: String, price: Double, quantity: Int)
val products = List(
Product("Laptop", 999.99, 5),
Product("Mouse", 29.99, 20),
Product("Keyboard", 79.99, 15)
)
def generateReport(): String = {
val header = "Product Inventory Report"
val separator = "=" * header.length
val reportLines = products.map { product =>
f"${product.name}%-15s ${product.price}%8.2f ${product.quantity}%5d ${product.price * product.quantity}%10.2f"
}
s"""
|$header
|$separator
|${"Product"}%-15s ${"Price"}%8s ${"Qty"}%5s ${"Total"}%10s
|${"-" * 50}
|${reportLines.mkString("\n")}
|${"-" * 50}
|Total Value: ${f"${products.map(p => p.price * p.quantity).sum}%.2f"}
""".stripMargin
}
def main(args: Array[String]): Unit = {
println(generateReport())
}
}总结
本章详细介绍了 Scala 中的各种字面量:
- 数值字面量:整数、浮点数的各种表示方法
- 字符字面量:字符、转义字符、Unicode 字符
- 字符串字面量:普通字符串、原始字符串、字符串插值
- 集合字面量:数组、列表、集合、映射的字面量语法
- 特殊字面量:布尔值、符号、函数、正则表达式
掌握字面量的使用是编写清晰、简洁 Scala 代码的基础。在下一章中,我们将学习 Scala 转义字符,深入了解字符串中特殊字符的处理方法。