3.1.1 常量变量
表达式:是可计算的语句,如 “1 + 1”
代码块:组合几个表达式,用“ {} ”包围起来;代码块中最后一个表达式的结果是整个块的结果
常量:使用“val”关键字声明,且必须初始化时赋值,之后不能被重新赋值
变量:使用“var”关键字声明,且必须初始化时赋值,之后可以被重新赋值;它是程序的基本组成单位
基本语法:var | val 变量名[: 变量类型] = 变量值
scala> var age = 23
age: Int = 23
scala> age = 26
age: Int = 26
scala> println(age.isInstanceOf[Int])
true
scala> val name: String = "zhangsan"
name: String = zhangsan
scala> name = "lisi"
<console>:12: error: reassignment to val
name = "lisi"
^
📝 注意事项
- 声明/定义变量时,使用 var/val 修饰,var 修饰的变量可以改变,val修饰的不可改
- 声明变量时,变量类型可以省略(编译器可以自动推导,即类型推导),但是必须初始化
- 声明变量时,类型确定后,就不能修改,说明 Scala 是强数据类型语言
- val 修饰的变量在编译,等同于加上了 final 关键字,具体可以反编译查看底层源代码
- 实际开发中,经常操作一个对象的属性,建议使用 val 声明实例;因为没有线程安全问题,效率高
3.1.2 层次结构
在 Scala 中,所有的值都有类型,包括数值和函数;Scala 所有的数据类型都是对象 ```scala val list: List[Any] = List( “hello”, 123, ‘y’, true, () => “this is a function” ) list.foreach(ele => print(ele + “ “))
// 执行结果如下:(最后还有一个空格)
// hello 123 y true
👉下图阐述了类型层次结构的一个子集<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/742178/1601355836644-1e5c1387-7ac5-40fa-8451-d9d9151d6201.png#align=left&display=inline&height=432&margin=%5Bobject%20Object%5D&name=image.png&originHeight=576&originWidth=1353&size=82443&status=done&style=stroke&width=1015)
<a name="1LR9w"></a>
## 数据类型
| **数据类型** | **描述** |
| :---: | :---: |
| **Any** | 所有类型的超类型(也称为顶级类型) |
| **AnyVal** | 值类型 |
| **AnyRef** | 引用类型(即所有非值类型) |
| **Null** | 所有引用类型的子类型(即 AnyRef 的任意子类型) |
| **Nothing** | 所有类型的子类型(也称为底部类型) |
**📝 类型解说**
- Any 定义了一些通用的方法如 `equals`、`hashCode`、`toString`
- AnyVal 有9个预定义的非空的值类型(**_见下面值类型_**)
- AnyRef 应用在 Java 的运行环境中时,相当于 `java.lang.Object`
- Null 有一个单例值 null;主要是使 Scala 满足和其他 JVM 语言的互操作性,不应该在 Scala 代码中使用
- Nothing 用途之一是给出非正常终止的信号,如抛出异常、程序退出或一个无限循环;没有一个值是该类型的
<a name="dyDJD"></a>
## 值类型
| **值类型** | **描述** | **数值区间** |
| :---: | :---: | :---: |
| **Byte** | 8 位有符号补码整数 | -2 ~ 2 - 1 |
| **Short** | 16 位有符号补码整数 | -2 ~ 2 - 1 |
| **Int** | 32 位有符号补码整数 | -2 ~ 2 - 1 |
| **Long** | 64 位有符号补码整数 | -2 ~ 2 - 1 |
| **Float** | 32 位, IEEE 754 标准的单精度浮点数 | |
| **Double** | 64 位, IEEE 754 标准的双精度浮点数 | |
| **Char** | 16 位无符号 Unicode 字符 | 0 ~ 2 - 1 |
| **Boolean** | 布尔值 | ture or false |
| **Unit** | 不带任何意义的值类型 | 无值 |
**📝 说明**
- 在 Scala 中,小数默认是 Double 类型,整数默认是 Int 类型
- Unit 仅有一个实例,可以用 **`()`** 声明;当一个函数返回空时使用它
<a name="XZOlC"></a>
# 3.1.3 类型转换
该节内容只针对值类型
<a name="c9awT"></a>
## 隐式类型转换
值类型可以按照下面的方向进行转换,该转换方向是_**单向的**_
```scala
// corrent
val x: Long = 987654321
val y: Float = x // 9.8765434E8(损失了一些精度)
val face: Char = '☺'
val number: Int = face // 63
// error: type mismatch
val z: Long = y
强制类型转换
强制类型转换可能会损失精度;主要掌握字符串和其他值类型之间的转换方法
// (1) error: Short -> Int
var s: Short = 5
s = s - 2
// (2) correct
var b: Byte = 3
b = (b + 4).toByte
3.1.4 使用细节
- 整数类型
- 都有最大最小值,属性分别是 MaxValue 和 MinValue
- 声明变量为 Long 类型时,使用类型推导,末尾加上 “l 或 L”
- 浮点类型
- 都有最大最小值,属性分别是 MaxValue 和 MinValue
- 声明变量为 Float 类型时,使用类型推导,末尾加上 “f 或 F”
- 浮点型常量有两种表示形式:十进制数和科学计数法形式,如 .512、5.12e2
字符类型
当左右两边都是数值型时,做加法运算
- 当左右两边有一方是字符串,做拼接运算
- 当左右两边一方是字符,一方是 Int 类型时,做加法运算,并类型转换
println(22 + 33) // 55
println(22 + "ha") // 22ha
println('a' + 1) // 98
var ch = 'a' + 1
println(ch) // b