一、概述
Scala 是一门强类型语言,支持多种数据类型。与 Java 不同,Scala 中所有数据类型都是对象,没有原生类型(primitive types)的概念。这意味着你可以在基本类型上调用方法。
核心思想
- 纯面向对象:所有数据类型都是对象,可以调用方法
- 类型推断:编译器可以自动推断变量类型
- 统一类型系统 :所有类型都继承自
Any
二、类型层次结构
Scala 拥有统一的类型系统,所有类型都继承自 Any。
Any
|
----------+----------
| |
AnyVal AnyRef
| |
------+------ ---+---
| | | | |
Int Double ... String 其他引用类型
| |
Unit Null
| |
Nothing Nothing
类型层次说明
| 类型 | 描述 |
|---|---|
| Any | 所有类型的超类型,定义了 ==、!=、equals、hashCode、toString 等通用方法 |
| AnyVal | 所有值类型的超类型,包括 Int、Double、Boolean 等 |
| AnyRef | 所有引用类型的超类型,等价于 Java 中的 Object |
| Unit | 表示无值,相当于 Java 中的 void |
| Null | 所有引用类型的子类型,表示空引用 |
| Nothing | 所有类型的子类型,表示无返回值类型 |
Any 类型示例
scala
val list: List[Any] = List(
"a string", // String
732, // Int
'c', // Char
true, // Boolean
() => "an anonymous function returning a string" // 函数
)
list.foreach(element => println(element))
三、基本数据类型
数值类型
| 类型 | 描述 | 范围 | Scala 标准库类 |
|---|---|---|---|
| Byte | 8位有符号整数 | -128 到 127 | scala.Byte |
| Short | 16位有符号整数 | -32768 到 32767 | scala.Short |
| Int | 32位有符号整数 | -2147483648 到 2147483647 | scala.Int |
| Long | 64位有符号整数 | -9223372036854775808 到 9223372036854775807 | scala.Long |
| Float | 32位 IEEE 754 单精度浮点数 | IEEE 754 标准 | scala.Float |
| Double | 64位 IEEE 754 双精度浮点数 | IEEE 754 标准 | scala.Double |
其他基本类型
| 类型 | 描述 | Scala 标准库类 |
|---|---|---|
| Char | 16位无符号 Unicode 字符 | scala.Char |
| Boolean | 布尔类型,值为 true 或 false |
scala.Boolean |
| String | 字符串类型,表示字符序列 | java.lang.String |
数值类型声明示例
scala
val b: Byte = 1
val s: Short = 1
val i: Int = 1
val l: Long = 1L
val f: Float = 3.0f
val d: Double = 2.0
类型推断示例
scala
val i = 1 // Int
val d = 1.1 // Double
val l = 1L // Long
val f = 1.0f // Float
显式类型转换
scala
val a: Byte = 0
val a: Double = 0 // Double = 0.0
val a: Float = 0 // Float = 0.0
val a: Int = 0 // Int = 0
val a: Long = 0 // Long = 0
val a: Short = 0 // Short = 0
大数类型
scala
val x = BigInt(1_234_456_789)
val y = BigDecimal(1_234_456.890)
四、集合类型
Scala 集合分为 不可变(immutable) 和 可变(mutable) 两种。
主要集合类型
| 类型 | 描述 | Scala 标准库类 |
|---|---|---|
| List | 不可变链表 | scala.collection.immutable.List |
| Vector | 不可变索引序列 | scala.collection.immutable.Vector |
| Set | 不可变集合(无重复元素) | scala.collection.immutable.Set |
| Map | 不可变键值对集合 | scala.collection.immutable.Map |
| Array | 可变数组 | scala.Array |
| ArrayBuffer | 可变索引序列 | scala.collection.mutable.ArrayBuffer |
| Tuple | 可包含不同类型元素的不可变容器 | scala.TupleN |
| Option | 代表有可能含有值或为空的容器 | scala.Option |
| Either | 表示两种可能的值类型之一 | scala.util.Either |
| Try | 处理操作结果可能成功或失败的容器 | scala.util.Try |
不可变集合示例
scala
val strings = List("a", "b", "c")
val vector = Vector("a", "b", "c")
val set = Set("a", "b", "a") // 结果: Set("a", "b"),自动去重
val map = Map(
"a" -> 1,
"b" -> 2,
"c" -> 3
)
可变集合示例
scala
import scala.collection.mutable
val arrayBuffer = mutable.ArrayBuffer("a", "b", "c")
val mutableSet = mutable.Set(1, 2, 3)
val mutableMap = mutable.Map("a" -> 1, "b" -> 2)
不可变 vs 可变集合操作
scala
// 不可变 Set
var s_immutable = Set(1, 2, 3)
s_immutable += 4 // s_immutable = s_immutable + 4,创建新集合
s_immutable -= 2 // s_immutable = s_immutable - 2,创建新集合
// 可变 Set
val s_mutable = collection.mutable.Set(1, 2, 3)
s_mutable += 4 // 原地修改
s_mutable -= 2 // 原地修改
统一返回类型原则
Scala 集合操作返回相同类型的集合:
scala
List(1, 2, 3).map(_ + 1) // 返回 List[Int] = List(2, 3, 4)
Set(1, 2, 3).map(_ * 2) // 返回 Set[Int] = Set(2, 4, 6)
五、Tuple(元组)
元组是一个可以包含不同类型元素的不可变容器。
scala
val tupleValue: (Int, String, Boolean) = (42, "Answer", true)
// 访问元素(从1开始索引)
println(tupleValue._1) // 42
println(tupleValue._2) // "Answer"
println(tupleValue._3) // true
六、Option 类型
Option 是一个容器,表示一个值可能存在或不存在,用于避免空指针异常。
Option 的两个子类
- Some(value):表示有值
- None:表示无值
创建 Option
scala
val someValue: Option[String] = Some("I am here")
val noneValue: Option[String] = None
使用模式匹配处理 Option
scala
def toInt(s: String): Option[Int] = {
try {
Some(Integer.parseInt(s))
} catch {
case _: NumberFormatException => None
}
}
toInt("5") match {
case Some(i) => println(s"转换成功: $i")
case None => println("转换失败")
}
使用 getOrElse 获取值或默认值
scala
val result = toInt("abc").getOrElse(0) // 如果转换失败返回 0
// 等价于
val result2 = toInt("abc") match {
case Some(x) => x
case None => 0
}
七、Either 类型
Either 表示两种可能的值类型之一,通常用于错误处理。
两个子类
- Left(value):通常表示错误
- Right(value):通常表示成功
scala
val eitherValue: Either[String, Int] = Right(42)
val errorValue: Either[String, Int] = Left("Error occurred")
eitherValue match {
case Right(value) => println(s"成功: $value")
case Left(error) => println(s"错误: $error")
}
八、Try 类型
Try 用于处理可能抛出异常的操作。
两个子类
- Success(value):操作成功
- Failure(exception):操作失败
scala
import scala.util.{Try, Success, Failure}
val tryValue: Try[Int] = Try(10 / 2) // Success(5)
val failValue: Try[Int] = Try(10 / 0) // Failure(ArithmeticException)
tryValue match {
case Success(value) => println(s"成功: $value")
case Failure(exception) => println(s"失败: ${exception.getMessage}")
}
九、特殊类型
Unit 类型
Unit 表示无值,相当于 Java 中的 void。
scala
def printHello(): Unit = {
println("Hello, Scala!")
}
val unitValue: Unit = () // Unit 的唯一实例
Null 类型
Null 是所有引用类型的子类型,表示空引用。
scala
val nullValue: String = null
val nullRef: AnyRef = null
Nothing 类型
Nothing 是所有类型的子类型,表示无返回值类型。通常用于:
- 抛出异常的方法
- 无限循环
scala
def error(message: String): Nothing = {
throw new RuntimeException(message)
}
def infiniteLoop(): Nothing = {
while (true) {}
}
十、类型检查与转换
运行时类型检查
scala
val x: Any = "Hello Scala"
// 类型检查
if (x.isInstanceOf[String]) {
println("x is a String")
}
运行时类型转换
scala
val x: Any = "Hello Scala"
if (x.isInstanceOf[String]) {
val str: String = x.asInstanceOf[String]
println(s"转换后的值: $str")
}
编译时类型注解
scala
val x: Any = "Hello"
val str: String = x.asInstanceOf[String]
获取类的 Class 对象
scala
val stringClass = classOf[String]
十一、完整示例代码
scala
import scala.util.{Try, Success, Failure}
object DataTypeExamples {
def main(args: Array[String]): Unit = {
println("=== Scala 数据类型示例 ===\n")
// 基本类型
println("--- 基本类型 ---")
val byteValue: Byte = 127
val shortValue: Short = 32767
val intValue: Int = 2147483647
val longValue: Long = 9223372036854775807L
val floatValue: Float = 3.14f
val doubleValue: Double = 3.141592653589793
val charValue: Char = 'A'
val stringValue: String = "Hello, Scala!"
val booleanValue: Boolean = true
println(s"Byte: $byteValue")
println(s"Short: $shortValue")
println(s"Int: $intValue")
println(s"Long: $longValue")
println(s"Float: $floatValue")
println(s"Double: $doubleValue")
println(s"Char: $charValue")
println(s"String: $stringValue")
println(s"Boolean: $booleanValue")
// 集合类型
println("\n--- 集合类型 ---")
val listValue: List[Int] = List(1, 2, 3)
val setValue: Set[String] = Set("Scala", "Java", "Python")
val mapValue: Map[String, Int] = Map("one" -> 1, "two" -> 2, "three" -> 3)
val arrayValue: Array[Int] = Array(4, 5, 6)
val tupleValue: (Int, String, Boolean) = (42, "Answer", true)
println(s"List: $listValue")
println(s"Set: $setValue")
println(s"Map: $mapValue")
println(s"Array: ${arrayValue.mkString(", ")}")
println(s"Tuple: $tupleValue")
// Option 类型
println("\n--- Option 类型 ---")
val optionValue: Option[String] = Some("I am here")
val noneValue: Option[String] = None
println(s"Some: $optionValue")
println(s"None: $noneValue")
println(s"getOrElse: ${noneValue.getOrElse("default value")}")
// Either 类型
println("\n--- Either 类型 ---")
val eitherValue: Either[String, Int] = Right(42)
println(s"Either: $eitherValue")
// Try 类型
println("\n--- Try 类型 ---")
val tryValue: Try[Int] = Try(10 / 2)
println(s"Try: $tryValue")
// 特殊类型
println("\n--- 特殊类型 ---")
val unitValue: Unit = ()
val nullValue: String = null
println(s"Unit: $unitValue")
println(s"Null: $nullValue")
// Any 类型
println("\n--- Any 类型 ---")
val anyList: List[Any] = List("string", 732, 'c', true)
anyList.foreach(println)
// 类型检查与转换
println("\n--- 类型检查与转换 ---")
val x: Any = "Hello Scala"
if (x.isInstanceOf[String]) {
val str = x.asInstanceOf[String]
println(s"类型转换成功: $str")
}
}
}
十二、最佳实践
1. 优先使用不可变集合
scala
// 推荐
val list = List(1, 2, 3)
val map = Map("a" -> 1, "b" -> 2)
// 仅在必要时使用可变集合
import scala.collection.mutable
val buffer = mutable.ArrayBuffer(1, 2, 3)
2. 使用 Option 替代 null
scala
// 不推荐
def findUser(id: Int): User = null // 可能导致空指针异常
// 推荐
def findUser(id: Int): Option[User] = {
// 返回 Some(user) 或 None
}
3. 使用 Try 处理可能失败的操作
scala
// 不推荐
def divide(a: Int, b: Int): Int = a / b // 可能抛出异常
// 推荐
def divide(a: Int, b: Int): Try[Int] = Try(a / b)
4. 使用类型推断,但在必要时显式声明
scala
// 类型明显时,使用推断
val name = "Scala"
val numbers = List(1, 2, 3)
// 类型不明显或需要特定类型时,显式声明
val result: Double = 10 / 3.0
val empty: List[Int] = List.empty
十三、类型对比表
| 类型分类 | 类型 | 可变性 | 用途 |
|---|---|---|---|
| 值类型 | Byte, Short, Int, Long, Float, Double, Char, Boolean | 不可变 | 存储基本数据 |
| 引用类型 | String, 自定义类 | 不可变/可变 | 存储复杂数据 |
| 序列集合 | List, Vector, Array, ArrayBuffer | List/Vector 不可变,Array/ArrayBuffer 可变 | 存储有序元素 |
| Set 集合 | Set, mutable.Set | 默认不可变 | 存储无重复元素 |
| Map 集合 | Map, mutable.Map | 默认不可变 | 存储键值对 |
| 元组 | Tuple1 - Tuple22 | 不可变 | 存储固定数量的异构元素 |
| 安全容器 | Option, Either, Try | 不可变 | 安全处理可能缺失或失败的值 |
| 特殊类型 | Unit, Null, Nothing, Any | - | 特殊用途 |