Scala 数据类型

一、概述

Scala 是一门强类型语言,支持多种数据类型。与 Java 不同,Scala 中所有数据类型都是对象,没有原生类型(primitive types)的概念。这意味着你可以在基本类型上调用方法。

核心思想

  • 纯面向对象:所有数据类型都是对象,可以调用方法
  • 类型推断:编译器可以自动推断变量类型
  • 统一类型系统 :所有类型都继承自 Any

二、类型层次结构

Scala 拥有统一的类型系统,所有类型都继承自 Any

复制代码
                    Any
                     |
          ----------+----------
          |                   |
        AnyVal              AnyRef
          |                   |
    ------+------          ---+---
    |     |     |          |     |
  Int  Double  ...      String  其他引用类型
    |                   |
  Unit               Null
    |                   |
  Nothing           Nothing

类型层次说明

类型 描述
Any 所有类型的超类型,定义了 ==!=equalshashCodetoString 等通用方法
AnyVal 所有值类型的超类型,包括 IntDoubleBoolean
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 布尔类型,值为 truefalse 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 - 特殊用途

相关推荐
爱思考的小伙2 小时前
Qt-02:信号与槽
开发语言·qt
howard20052 小时前
1.2 Scala变量与数据类型
scala·变量·数据类型·常量
重生之后端学习2 小时前
136. 只出现一次的数字
开发语言·算法·leetcode·职场和发展·深度优先
元Y亨H2 小时前
Spring Cloud 微服务整合 Vue 前端:架构设计与核心原理
后端·spring cloud
啊唯不困2 小时前
AI智能应用开发(Java)起点-终点 -1、java的前世今生andJava环境配置、jdk下载,以及Idea下载和基本应用
java·开发语言·intellij-idea
大迪deblog2 小时前
系统架构设计-软件架构风格
java·开发语言·架构·软件构建
盐水冰2 小时前
【烘焙坊项目】后端搭建(10) - 地址簿功能&用户下单&微信支付
java·数据库·后端
csbysj20202 小时前
Bootstrap 弹出框
开发语言
重庆小透明2 小时前
【面试问题】java小厂
java·开发语言·面试