Skip to content

Scala 数据类型

Scala 拥有丰富而强大的类型系统,本章将详细介绍 Scala 的各种数据类型,包括基本类型、引用类型和类型层次结构。

类型层次结构

Scala 的类型系统有一个统一的层次结构:

Any
├── AnyVal (值类型)
│   ├── Double
│   ├── Float
│   ├── Long
│   ├── Int
│   ├── Short
│   ├── Byte
│   ├── Char
│   ├── Boolean
│   └── Unit
└── AnyRef (引用类型)
    ├── String
    ├── List
    ├── Option
    └── 所有其他引用类型

Any 类型

Any 是所有类型的超类型:

scala
val items: List[Any] = List(1, "hello", true, 3.14)

def printAny(x: Any): Unit = {
  println(s"Value: $x, Type: ${x.getClass.getSimpleName}")
}

items.foreach(printAny)
// 输出:
// Value: 1, Type: Integer
// Value: hello, Type: String
// Value: true, Type: Boolean
// Value: 3.14, Type: Double

基本数据类型(AnyVal)

数值类型

整数类型

scala
// Byte: 8位有符号整数 (-128 to 127)
val byteValue: Byte = 127
val byteMin: Byte = Byte.MinValue  // -128
val byteMax: Byte = Byte.MaxValue  // 127

// Short: 16位有符号整数 (-32,768 to 32,767)
val shortValue: Short = 32767
val shortMin: Short = Short.MinValue  // -32768
val shortMax: Short = Short.MaxValue  // 32767

// Int: 32位有符号整数 (-2^31 to 2^31-1)
val intValue: Int = 2147483647
val intMin: Int = Int.MinValue  // -2147483648
val intMax: Int = Int.MaxValue  // 2147483647

// Long: 64位有符号整数 (-2^63 to 2^63-1)
val longValue: Long = 9223372036854775807L
val longMin: Long = Long.MinValue
val longMax: Long = Long.MaxValue

浮点类型

scala
// Float: 32位IEEE 754单精度浮点数
val floatValue: Float = 3.14159f
val floatMin: Float = Float.MinValue
val floatMax: Float = Float.MaxValue
val floatPositiveInfinity: Float = Float.PositiveInfinity
val floatNegativeInfinity: Float = Float.NegativeInfinity
val floatNaN: Float = Float.NaN

// Double: 64位IEEE 754双精度浮点数
val doubleValue: Double = 3.141592653589793
val doubleMin: Double = Double.MinValue
val doubleMax: Double = Double.MaxValue
val pi: Double = math.Pi
val e: Double = math.E

数值类型转换

scala
val intVal = 42
val longVal: Long = intVal.toLong      // 安全转换
val doubleVal: Double = intVal.toDouble // 安全转换
val floatVal: Float = intVal.toFloat   // 安全转换

// 可能丢失精度的转换
val bigLong = 1234567890123L
val intFromLong: Int = bigLong.toInt   // 可能溢出

// 检查转换是否安全
def safeToInt(long: Long): Option[Int] = {
  if (long >= Int.MinValue && long <= Int.MaxValue) {
    Some(long.toInt)
  } else {
    None
  }
}

字符类型

scala
// Char: 16位无符号Unicode字符
val char1: Char = 'A'
val char2: Char = '\u0041'  // Unicode 表示的 'A'
val char3: Char = 65.toChar // ASCII 码转字符

// 字符操作
val isLetter: Boolean = char1.isLetter
val isDigit: Boolean = char1.isDigit
val isUpper: Boolean = char1.isUpper
val lower: Char = char1.toLower
val upper: Char = char1.toUpper

// 字符范围
val charMin: Char = Char.MinValue  // '\u0000'
val charMax: Char = Char.MaxValue  // '\uffff'

布尔类型

scala
// Boolean: true 或 false
val isTrue: Boolean = true
val isFalse: Boolean = false

// 布尔运算
val and: Boolean = true && false   // false
val or: Boolean = true || false    // true
val not: Boolean = !true          // false

// 条件表达式
val result: String = if (isTrue) "yes" else "no"

// 布尔值与其他类型的关系
val boolToInt: Int = if (isTrue) 1 else 0

Unit 类型

scala
// Unit: 表示无有意义的值,类似于 Java 的 void
def printMessage(msg: String): Unit = {
  println(msg)
}

val unitValue: Unit = ()  // Unit 的唯一值
val unitFromMethod: Unit = printMessage("Hello")

// Unit 在表达式中的使用
val result: Unit = {
  val x = 10
  val y = 20
  println(s"Sum: ${x + y}")  // 返回 Unit
}

引用类型(AnyRef)

字符串类型

scala
// String: 不可变字符序列
val str1: String = "Hello, World!"
val str2: String = new String("Hello")

// 字符串操作
val length: Int = str1.length
val upper: String = str1.toUpperCase
val lower: String = str1.toLowerCase
val substring: String = str1.substring(0, 5)  // "Hello"

// 字符串比较
val isEqual: Boolean = str1 == "Hello, World!"  // true
val isEqualRef: Boolean = str1 eq str2          // false (引用比较)

// 字符串插值
val name = "Alice"
val age = 25
val interpolated = s"Name: $name, Age: $age"
val formatted = f"Pi: ${math.Pi}%.2f"
val raw = raw"Path: C:\Users\$name"

集合类型概览

scala
// List: 不可变链表
val list: List[Int] = List(1, 2, 3, 4, 5)
val emptyList: List[String] = List.empty[String]
val nilList: List[Int] = Nil

// Array: 可变数组
val array: Array[Int] = Array(1, 2, 3, 4, 5)
val arrayOfStrings: Array[String] = Array("a", "b", "c")

// Vector: 不可变向量
val vector: Vector[Int] = Vector(1, 2, 3, 4, 5)

// Set: 不可变集合
val set: Set[Int] = Set(1, 2, 3, 2, 1)  // Set(1, 2, 3)

// Map: 不可变映射
val map: Map[String, Int] = Map("a" -> 1, "b" -> 2, "c" -> 3)

选项类型(Option)

scala
// Option: 表示可能存在或不存在的值
val someValue: Option[String] = Some("Hello")
val noneValue: Option[String] = None

// Option 的使用
def findUser(id: Int): Option[String] = {
  if (id > 0) Some(s"User$id") else None
}

val user1 = findUser(1)   // Some("User1")
val user2 = findUser(-1)  // None

// Option 的操作
val result1 = someValue.getOrElse("Default")  // "Hello"
val result2 = noneValue.getOrElse("Default")  // "Default"

val mapped = someValue.map(_.toUpperCase)     // Some("HELLO")
val filtered = someValue.filter(_.length > 3) // Some("Hello")

// 模式匹配
val message = someValue match {
  case Some(value) => s"Found: $value"
  case None => "Not found"
}

元组类型(Tuple)

scala
// 元组: 固定数量的不同类型元素
val tuple2: (String, Int) = ("Alice", 25)
val tuple3: (String, Int, Boolean) = ("Bob", 30, true)
val tuple4: (Int, String, Double, Boolean) = (1, "test", 3.14, false)

// 访问元组元素
val name: String = tuple2._1    // "Alice"
val age: Int = tuple2._2        // 25

// 元组解构
val (personName, personAge) = tuple2
println(s"Name: $personName, Age: $personAge")

// 元组的方法
val swapped: (Int, String) = tuple2.swap  // (25, "Alice")

函数类型

scala
// 函数类型
val add: (Int, Int) => Int = (x, y) => x + y
val multiply: (Int, Int) => Int = _ * _

// 高阶函数类型
val applyTwice: (Int => Int, Int) => Int = (f, x) => f(f(x))

// 使用函数类型
val double: Int => Int = _ * 2
val result = applyTwice(double, 5)  // 20

// 函数作为参数
def processNumbers(numbers: List[Int], operation: Int => Int): List[Int] = {
  numbers.map(operation)
}

val numbers = List(1, 2, 3, 4, 5)
val doubled = processNumbers(numbers, _ * 2)
val squared = processNumbers(numbers, x => x * x)

类型别名

scala
// 类型别名
type UserId = Int
type UserName = String
type UserData = (UserId, UserName, Int)  // (id, name, age)

val user: UserData = (1, "Alice", 25)

// 复杂类型别名
type StringToInt = String => Int
type UserMap = Map[UserId, UserName]

val userMap: UserMap = Map(1 -> "Alice", 2 -> "Bob")
val parser: StringToInt = _.toInt

泛型类型

scala
// 泛型类定义
class Container[T](val value: T) {
  def get: T = value
  def map[U](f: T => U): Container[U] = new Container(f(value))
}

// 使用泛型类
val intContainer = new Container(42)
val stringContainer = new Container("Hello")
val doubledContainer = intContainer.map(_ * 2)

// 泛型方法
def identity[T](x: T): T = x
def pair[A, B](a: A, b: B): (A, B) = (a, b)

val id1 = identity(42)        // Int
val id2 = identity("hello")   // String
val p = pair("key", 100)      // (String, Int)

类型推断

scala
// Scala 的类型推断
val number = 42              // 推断为 Int
val text = "Hello"           // 推断为 String
val flag = true              // 推断为 Boolean
val decimal = 3.14           // 推断为 Double

val list = List(1, 2, 3)     // 推断为 List[Int]
val map = Map("a" -> 1)      // 推断为 Map[String, Int]

// 需要显式类型注解的情况
val emptyList: List[String] = List()  // 无法推断元素类型
val recursive: Int => Int = x => if (x <= 0) 1 else x * recursive(x - 1)

类型检查和转换

scala
// 类型检查
val obj: Any = "Hello, World!"

val isString: Boolean = obj.isInstanceOf[String]
val isInt: Boolean = obj.isInstanceOf[Int]

// 类型转换
if (obj.isInstanceOf[String]) {
  val str: String = obj.asInstanceOf[String]
  println(str.toUpperCase)
}

// 安全的类型转换
obj match {
  case s: String => println(s"String: ${s.toUpperCase}")
  case i: Int => println(s"Integer: ${i * 2}")
  case _ => println("Unknown type")
}

Nothing 和 Null 类型

scala
// Nothing: 所有类型的子类型,表示永不返回
def error(message: String): Nothing = {
  throw new RuntimeException(message)
}

def divide(x: Int, y: Int): Int = {
  if (y == 0) error("Division by zero")
  else x / y
}

// Null: 所有引用类型的子类型
val nullString: String = null  // 不推荐使用
val nullList: List[Int] = null // 不推荐使用

// 使用 Option 代替 null
def safeDivide(x: Int, y: Int): Option[Int] = {
  if (y == 0) None else Some(x / y)
}

实际应用示例

类型安全的配置系统

scala
// 定义配置类型
sealed trait ConfigValue
case class StringConfig(value: String) extends ConfigValue
case class IntConfig(value: Int) extends ConfigValue
case class BooleanConfig(value: Boolean) extends ConfigValue

class Configuration {
  private var configs: Map[String, ConfigValue] = Map()
  
  def set(key: String, value: ConfigValue): Unit = {
    configs = configs + (key -> value)
  }
  
  def getString(key: String): Option[String] = {
    configs.get(key).collect {
      case StringConfig(value) => value
    }
  }
  
  def getInt(key: String): Option[Int] = {
    configs.get(key).collect {
      case IntConfig(value) => value
    }
  }
  
  def getBoolean(key: String): Option[Boolean] = {
    configs.get(key).collect {
      case BooleanConfig(value) => value
    }
  }
}

// 使用示例
val config = new Configuration()
config.set("app.name", StringConfig("MyApp"))
config.set("app.port", IntConfig(8080))
config.set("app.debug", BooleanConfig(true))

val appName = config.getString("app.name").getOrElse("DefaultApp")
val port = config.getInt("app.port").getOrElse(3000)
val debug = config.getBoolean("app.debug").getOrElse(false)

类型安全的 JSON 处理

scala
// 简化的 JSON 类型
sealed trait Json
case object JsonNull extends Json
case class JsonBoolean(value: Boolean) extends Json
case class JsonNumber(value: Double) extends Json
case class JsonString(value: String) extends Json
case class JsonArray(values: List[Json]) extends Json
case class JsonObject(fields: Map[String, Json]) extends Json

// JSON 构建器
object Json {
  def obj(fields: (String, Json)*): JsonObject = JsonObject(fields.toMap)
  def arr(values: Json*): JsonArray = JsonArray(values.toList)
  def str(value: String): JsonString = JsonString(value)
  def num(value: Double): JsonNumber = JsonNumber(value)
  def bool(value: Boolean): JsonBoolean = JsonBoolean(value)
  val `null`: JsonNull.type = JsonNull
}

// 使用示例
val json = Json.obj(
  "name" -> Json.str("Alice"),
  "age" -> Json.num(25),
  "active" -> Json.bool(true),
  "hobbies" -> Json.arr(
    Json.str("reading"),
    Json.str("swimming")
  ),
  "address" -> Json.obj(
    "city" -> Json.str("New York"),
    "zipcode" -> Json.str("10001")
  )
)

练习

练习 1:类型转换和检查

scala
object TypeExercise {
  def processValue(value: Any): String = {
    value match {
      case i: Int if i > 0 => s"Positive integer: $i"
      case i: Int if i < 0 => s"Negative integer: $i"
      case i: Int => "Zero"
      case s: String if s.nonEmpty => s"Non-empty string: $s"
      case s: String => "Empty string"
      case b: Boolean => s"Boolean: $b"
      case d: Double => f"Double: $d%.2f"
      case _ => "Unknown type"
    }
  }
  
  def main(args: Array[String]): Unit = {
    val values: List[Any] = List(42, -10, 0, "Hello", "", true, 3.14159, 'A')
    values.foreach(v => println(processValue(v)))
  }
}

练习 2:Option 类型应用

scala
object OptionExercise {
  case class Person(name: String, age: Int, email: Option[String])
  
  val people = List(
    Person("Alice", 25, Some("alice@example.com")),
    Person("Bob", 30, None),
    Person("Charlie", 35, Some("charlie@example.com"))
  )
  
  def findPersonByName(name: String): Option[Person] = {
    people.find(_.name == name)
  }
  
  def getEmailDomain(person: Person): Option[String] = {
    person.email.map(_.split("@").last)
  }
  
  def main(args: Array[String]): Unit = {
    val alice = findPersonByName("Alice")
    val domain = alice.flatMap(getEmailDomain)
    
    println(s"Alice's email domain: ${domain.getOrElse("No email")}")
    
    // 链式操作
    val result = for {
      person <- findPersonByName("Charlie")
      email <- person.email
      domain = email.split("@").last
    } yield s"${person.name}'s domain is $domain"
    
    println(result.getOrElse("Person not found or no email"))
  }
}

总结

本章详细介绍了 Scala 的数据类型系统:

  • 类型层次结构:Any、AnyVal、AnyRef 的关系
  • 基本类型:数值、字符、布尔、Unit 类型
  • 引用类型:字符串、集合、Option 等
  • 复合类型:元组、函数类型
  • 类型系统特性:泛型、类型推断、类型检查
  • 特殊类型:Nothing、Null 的使用场景

理解 Scala 的类型系统是掌握这门语言的关键。在下一章中,我们将学习 Scala 字面量,深入了解各种数据的字面量表示方法。

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