Skip to content

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 // Double

Float 字面量

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 转义字符,深入了解字符串中特殊字符的处理方法。

本站内容仅供学习和研究使用。