一、为什么需要变量
1.1 程序世界与对象
一个程序就是一个世界。在Scala中,一切都是对象。变量是程序的基本组成单位,无论是使用哪种高级程序语言编写程序,变量都是其程序的基本组成单位。

💡 Scala变量特点:Scala中的变量声明时必须初始化,这与Java有所不同,体现了Scala对类型安全的严格要求。
1.2 变量的概念
变量相当于内存中一个数据存储空间的表示。你可以把变量看做是一个房间的门牌号:
- 通过门牌号 → 找到房间
- 通过变量名 → 访问变量的值
1.3 变量使用的基本步骤
1. 声明/定义变量(Scala要求变量声明时必须初始化)
2. 使用变量
二、Scala变量基本使用
2.1 变量声明入门案例
scala
package com.atguigu.chapter02
object ScalaFunDemo01 {
def main(args: Array[String]): Unit = {
var a: Int = 1 // 定义一个整型变量,取名a,赋初值1
var b: Int = 3 // 定义一个整型变量,取名b,赋初值3
b = 89 // 给变量b赋89
println("a=" + a) // 输出变量a的值
println("b=" + b) // 输出变量b的值
}
}

2.2 多种类型变量声明
scala
// 声明变量【告诉计算机要开一个房间,并赋值】
var num : Int = 0 // 整型
var score : Double = 1.0 // 双精度浮点型
var gender : Char = 'N' // 字符型
var name : String = "scott" // 字符串型
三、Scala变量使用说明
3.1 变量声明基本语法
var | val 变量名 [: 变量类型] = 变量值
3.2 注意事项(重点)
1️⃣ 类型可以省略(类型推导)
声明变量时,类型可以省略,编译器会自动推导:
scala
var num1 = 10 // 编译器自动推导为Int类型
var name = "Tom" // 编译器自动推导为String类型
2️⃣ 类型确定后不可修改(强类型语言)
类型确定后,就不能修改,说明Scala是强数据类型语言:
scala
var a: Int = 10
// a = "hello" // 错误!不能将String赋值给Int
3️⃣ var与val的区别(核心)
在声明/定义一个变量时,可以使用 var 或者 val 来修饰:
| 修饰符 | 含义 | 特点 |
|---|---|---|
| var | variable | 修饰的变量可改变(可变变量) |
| val | value | 修饰的变量不可改(不可变变量,类似final) |
scala
var num1 = 10 // num1可以重新赋值
num1 = 20 // OK
val num2 = 20 // num2不可重新赋值
// num2 = 30 // 错误!编译报错
⚠️ 最佳实践 :在Scala编程中,优先使用val。因为不可变数据是函数式编程的核心,可以避免很多并发问题。
4️⃣ val底层等同于final
val 修饰的变量在编译后,等同于加上了 final:
scala
// Scala代码
val num2 = 20
// 反编译后类似Java代码
public final int num2 = 20;
5️⃣ 对象引用与对象状态的区别
var 修饰的对象引用可以改变,val 修饰的则不可改变,但对象的状态(值)却是可以改变的:
scala
class Dog {
var age = 100
}
val dog = new Dog() // dog引用不可变
dog.age = 200 // 但dog对象的age属性可以改变!
// dog = new Dog() // 错误!引用不能变
6️⃣ 变量声明时必须初始化
scala
var a: Int // 错误!没有初始化
var b: Int = 0 // OK
四、程序中 + 号的使用
在Scala中,+ 号有两种用法:
- 当左右两边都是数值型时 → 做加法运算
- 当左右两边有一方为字符串时 → 做拼接运算
scala
var name : String = "kristina"
var score : Double = 89.9
println(10 + 20) // 30,数值相加
println("hello" + "world") // helloworld,字符串拼接
println("score=" + score) // score=89.9,字符串拼接
五、Scala数据类型体系
5.1 数据类型介绍
Scala与Java有着相同的数据类型,但有一个重要区别:
🌟 在Scala中,数据类型都是对象! 也就是说,Scala没有Java中的原生类型(primitive type)。
Scala数据类型分为两大类:
- AnyVal(值类型)
- AnyRef(引用类型)
注意:不管是AnyVal还是AnyRef,都是对象!
5.2 Scala数据类型体系一览图

5.3 相对于Java的类型系统
相对于Java的类型系统,Scala要复杂些!也正是这复杂多变的类型系统,才让面向对象编程 和函数式编程完美地融合在了一起。
六、Scala数据类型列表
| 数据类型 | 描述 |
|---|---|
| Byte | 8位有符号补码整数,数值区间为 -128 到 127 |
| Short | 16位有符号补码整数,数值区间为 -32768 到 32767 |
| Int | 32位有符号补码整数,数值区间为 -2147483648 到 2147483647 |
| Long | 64位有符号补码整数 |
| Float | 32位,IEEE 754标准的单精度浮点数 |
| Double | 64位,IEEE 754标准的双精度浮点数 |
| Char | 16位无符号Unicode字符,区间值为 U+0000 到 U+FFFF |
| String | 字符序列 |
| Boolean | true或false |
| Unit | 表示无值,和其他语言中void等同。Unit只有一个实例值,写成 () |
| Null | null |
| Nothing | Nothing类型在Scala的类层级的最低端;它是任何其他类型的子类型 |
| Any | Any是所有其他类的超类 |
| AnyRef | AnyRef类是Scala里所有引用类(reference class)的基类 |
七、整数类型详解
7.1 基本介绍
Scala的整数类型就是用于存放整数值的,比如 12, 30, 3456 等等。
7.2 整型的类型
| 数据类型 | 占用空间 | 数值范围 |
|---|---|---|
| Byte [1] | 1字节 | -128 到 127 |
| Short [2] | 2字节 | -32768 到 32767 |
| Int [4] | 4字节 | -2147483648 到 2147483647 |
| Long [8] | 8字节 | -9223372036854775808 到 9223372036854775807 |
7.3 整型使用细节
1️⃣ 固定长度,不受OS影响
Scala各整数类型有固定的表数范围和字段长度,不受具体OS的影响,以保证Scala程序的可移植性。
2️⃣ 整型常量默认为Int型
Scala的整型常量/字面量 默认为 Int 型,声明Long型常量须后加 l 或 L:
scala
var c = 11 // c就是Int类型
var d = 12l // d就是Long类型
var e = 12L // d就是Long类型(推荐大写L,易区分)
3️⃣ 优先使用Int
Scala程序中变量常声明为Int型,除非不足以表示大数,才使用Long:
scala
// 这个值超出了Int范围,会报错
var e = 9223372036854775807 // 错误!
// 正确做法:加L声明为Long
var e = 9223372036854775807L // OK
八、浮点类型详解
8.1 基本介绍
Scala的浮点类型可以表示一个小数,比如 123.4f, 7.8, 0.12 等等。
8.2 浮点型的分类
| 数据类型 | 占用空间 | 说明 |
|---|---|---|
| Float [4] | 4字节 | 32位,IEEE 754标准的单精度浮点数 |
| Double [8] | 8字节 | 64位,IEEE 754标准的双精度浮点数 |
8.3 浮点型使用细节
1️⃣ 固定长度,不受OS影响
与整数类型类似,Scala浮点类型也有固定的表数范围和字段长度。
2️⃣ 浮点型常量默认为Double型
声明Float型常量,须后加 f 或 F:
scala
var f1: Float = 1.1 // 错误!double不能自动转float
var f2 = 1.2 // OK,类型推导为Double
var f3: Double = 1.3 // OK
var f4: Float = 1.4f // OK,声明为Float
var f5: Double = 1.5f // OK,float可以自动提升为double
3️⃣ 浮点型常量的两种表示形式
scala
// 十进制数形式
var d1 = 5.12
var d2 = 512.0f
var d3 = .512 // 必须有小数点
// 科学计数法形式
var d4 = 5.12e2 // 5.12 × 10² = 512.0
var d5 = 5.12E-2 // 5.12 × 10⁻² = 0.0512
4️⃣ 推荐使用Double
通常情况下,应该使用Double型,因为它比Float型更精确(小数点后大致7位):
scala
// 测试精度差异
var f: Float = 2.2345678912f // 精度损失
var d: Double = 2.2345678912 // 更精确
九、字符类型(Char)
9.1 基本介绍
字符类型可以表示单个字符 ,字符类型是 Char,16位无符号Unicode字符(2个字节),区间值为 U+0000 到 U+FFFF。
9.2 案例演示
scala
var c1: Char = 'a' // OK
var c2: Char = '\t' // OK,转义字符
var c3: Char = '你' // OK,中文字符
var c4: Char = 97 // OK!可以直接赋整数,输出时会按Unicode字符输出
9.3 字符类型使用细节
1️⃣ 单引号括起来的单个字符
scala
var c1 = 'a' // OK
var c2 = '中' // OK
var c3 = '9' // OK
2️⃣ 允许使用转义字符
scala
var c3 = '\n' // 换行符
var c4 = '\t' // 制表符
3️⃣ 可以直接赋整数(Unicode码)
scala
var c: Char = 97 // 对应字符 'a'
println(c) // 输出: a
println(c.toInt) // 输出: 97
4️⃣ Char类型可以进行运算
Char类型相当于一个整数,因为它都对应有Unicode码:
scala
var c1: Char = 'a'
var num: Int = 10 + c1 + 'b' // OK!
// 问题:下面正确吗?
var c2: Char = 'a' + 1 // 错误!'a'+1结果是Int,不能赋给Char
9.4 字符类型本质探讨
存储:字符 → 码值 → 二进制 → 存储
读取:二进制 → 码值 → 字符 → 读取
字符和码值的对应关系是通过字符编码表决定的(是规定好的),这一点和Java一样。
十、布尔类型(Boolean)
10.1 基本介绍
- 布尔类型也叫Boolean类型,Boolean类型数据只允许取值
true和false - Boolean类型占1个字节
- Boolean类型适于逻辑运算,一般用于程序流程控制:
scala
// if条件控制语句
if (flag) { ... }
// while循环控制语句
while (condition) { ... }
// do-while循环控制语句
do { ... } while (condition)
// for循环控制语句
for (i <- 1 to 10) { ... }
十一、Unit类型、Null类型和Nothing类型
11.1 基本说明
| 类型 | 说明 |
|---|---|
| Unit | 表示无值,和其他语言中void等同。用作不返回任何结果的方法的结果类型。Unit只有一个实例值,写成 () |
| Null | null,Null类型只有一个实例值 null |
| Nothing | Nothing类型在Scala的类层级的最低端;它是任何其他类型的子类型。当一个函数确定没有正常的返回值,可以用Nothing来指定返回类型 |
11.2 使用细节和注意事项
1️⃣ Null类
Null类只有一个实例对象 null,类似于Java中的null引用。null可以赋值给任意引用类型(AnyRef),但是不能赋值给值类型(AnyVal):
scala
var str: String = null // OK,String是引用类型
// var i: Int = null // 错误!Int是值类型
2️⃣ Unit类型
Unit类型用来标识过程,也就是没有明确返回值的函数。类似于Java里的void。Unit只有一个实例 ():
scala
def sayOk(): Unit = {
println("sayOk被调用")
}
// 等价于
val result: Unit = ()
3️⃣ Nothing类型
Nothing可以作为没有正常返回值的方法的返回类型,非常直观地告诉你这个方法不会正常返回。而且由于Nothing是其他任意类型的子类,它还能跟要求返回值的方法兼容:
scala
def test(): Nothing = {
throw new Exception("异常")
}
十二、值类型转换
12.1 值类型隐式转换
介绍
当Scala程序在进行赋值 或者运算 时,精度小的类型自动转换为精度大的数据类型,这个就是自动类型转换(隐式转换)。
数据类型按精度(容量)大小排序
Byte → Short → Int → Long → Float → Double
↑
Char

自动类型转换细节说明
-
多种类型混合运算:系统首先自动将所有数据转换成容量最大的那种数据类型,然后再进行计算
scalavar result: Double = 5.6 + 10 // 10先转为Double,结果是Double -
大容量赋值给小容量会报错:当我们把精度(容量)大的数据类型赋值给精度(容量)小的数据类型时,就会报错
scalavar b: Byte = 10 // b = 1000 // 错误!Int不能自动转Byte -
(Byte, Short)和Char之间不会相互自动转换
scalavar b: Byte = 10 // var c: Char = b // 错误! -
Byte、Short、Char三者可以计算:在计算时首先转换为Int类型
scalavar b: Byte = 10 var c: Char = 90 var s: Short = b + c // 错误!结果是Int var s2 = b + c // OK,类型推导为Int -
自动提升原则:表达式结果的类型自动提升为操作数中最大的类型
12.2 强制类型转换
介绍
自动类型转换的逆过程,将容量大的数据类型转换为容量小的数据类型。使用时要加上强制转函数,但可能造成精度降低或溢出,格外要注意。

Scala vs Java 强制转换对比
java
// Java方式
int num = (int)2.5; // 截断小数部分
scala
// Scala方式(一切都是对象,调用方法)
var num: Int = 2.7.toInt // 结果是2
强制类型转换细节说明
-
从大 → 小,需要使用强制转换
-
强转符号只针对于最近的操作数有效,往往会使用小括号提升优先级:
scalaval num1: Int = 10 * 3.5.toInt + 6 * 1.5.toInt // 36 // 等价于: 10*3 + 6*1 = 36 val num2: Int = (10 * 3.5 + 6 * 1.5).toInt // 44 // 先计算括号内: 35 + 9 = 44,再转Int -
Char类型可以保存Int的常量值,但不能保存Int的变量值,需要强转
scalavar c: Char = 97 // OK,常量在范围内 var i: Int = 97 // var c2: Char = i // 错误! var c2: Char = i.toChar // OK,强制转换 -
Byte和Short类型在进行运算时,当做Int类型处理
12.3 课堂练习题
判断是否能够通过编译,并说明原因:
scala
// 1)
var s: Short = 5 // OK
// s = s - 2 // 错误!s-2结果是Int,Int -> Short报错
// 2)
var b: Byte = 3 // OK
// b = b + 4 // 错误!b+4结果是Int
b = (b + 4).toByte // OK,使用强制转换
// 3)
var c: Char = 'a' // OK
var i: Int = 5 // OK
var d: Float = .314F // OK
var result: Double = c + i + d // OK!Float -> Double
// 4)
var b: Byte = 5 // OK
var s: Short = 3 // OK
// var t: Short = s + b // 错误!s+b结果是Int
var t2 = s + b // OK,类型推导为Int
12.4 高级隐式转换和隐式函数
Scala还提供了非常强大的隐式转换机制(隐式函数、隐式类等等),我们放在高级部分专门用一个章节来讲解。
十三、值类型和String类型的转换
13.1 基本类型转String类型
语法 :将基本类型的值 + "" 即可
scala
var str1 = true + "" // "true"
var str2 = 4.5 + "" // "4.5"
var str3 = 100 + "" // "100"
13.2 String类型转基本数据类型
语法 :通过String的 toXxx 方法即可
scala
var s = "12"
s.toInt // 12
s.toFloat // 12.0
s.toDouble // 12.0
s.toByte // 12
s.toLong // 12
s.toShort // 12
13.3 注意事项
-
在将String类型转成基本数据类型时,要确保String类型能够转成有效的数据 。比如可以把
"123"转成一个整数,但是不能把"hello"转成一个整数 -
思考 :要把
"12.5"转成 Int?scalavar s = "12.5" // s.toInt // 错误!会抛NumberFormatException s.toDouble.toInt // 先转Double,再转Int,结果是12
十四、标识符的命名规范
14.1 标识符概念
- Scala对各种变量、方法、函数 等命名时使用的字符序列称为标识符
- 凡是自己可以起名字的地方都叫标识符
14.2 标识符的命名规则(记住)
Scala中的标识符声明,基本和Java是一致的,但细节上会有所变化:
- 首字符为字母,后续字符任意字母和数字,美元符号,可后接下划线
- 数字不可以开头
- 首字符为操作符 (比如
+ - * /),后续字符也需跟操作符,至少一个 - 操作符 (比如
+ - * /)不能在标识符中间和最后 - 用反引号
...包括的任意字符串,即使是关键字(39个)也可以
14.3 标识符举例说明
scala
hello // OK
hello12 // OK
1hello // 错误!数字不能开头
h-b // 错误!中间不能有-
x h // 错误!不能有空格
h_4 // OK
_ab // OK
Int // OK,在Scala中Int不是关键字,而是预定义标识符(不推荐)
Float // OK
_ // 不可以!在Scala中_有很多其他作用
Abc // OK
+*- // OK,操作符开头,后续也是操作符
+a // 错误!操作符后不能跟字母
14.4 标识符命名注意事项
-
包名:尽量采取有意义的包名,简短,有意义
-
变量名、函数名、方法名 :采用驼峰法
scalavar userName = "Tom" // 小驼峰 def getUserInfo() = {} // 小驼峰
十五、Scala关键字
Scala有39个关键字:
package, import, class, object, trait, extends, with, type, forSome
private, protected, abstract, sealed, final, implicit, lazy, override
try, catch, finally, throw
if, else, match, case, do, while, for, return, yield
def, val, var
this, super
new
true, false, null
💡 注意 :在Scala中,
Int、Float等不是关键字,而是预定义标识符,可以用作变量名(但不推荐)。
本章知识回顾
| 知识点 | 核心内容 |
|---|---|
| 变量声明 | var 可变,val 不可变(推荐) |
| 类型推导 | 声明时可省略类型,编译器自动推导 |
| 数据类型 | 一切皆为对象,分为AnyVal和AnyRef |
| 整数类型 | Byte、Short、Int、Long,默认Int |
| 浮点类型 | Float、Double,默认Double |
| 特殊类型 | Unit(void)、Null、Nothing |
| 类型转换 | 隐式转换(小→大)、强制转换(大→小) |
| String转换 | +""转String,toXxx方法转基本类型 |
| 标识符 | 支持操作符命名,可用反引号包裹关键字 |
总结
本章我们深入学习了:
✅ Scala变量的声明与使用(var vs val)
✅ Scala完整的数据类型体系(AnyVal + AnyRef)
✅ 各种数据类型的详细说明和使用细节
✅ 值类型之间的隐式转换和强制转换
✅ 值类型与String类型之间的转换
✅ Scala标识符的命名规范和关键字