第二章 - 基本变量
Read Me
- ? Code : 本章节代码实现
- ? CSDN : wangt的博客
- ☁️ Github : https://github.com/lovewangtzq
- ❤️ 微信公众号 : 大数据初学者
- ? b站: 我学不会Spark
变量的基本使用 ❤️
-
如何定义一个变量 ❓
-
定义方法 : val 变量名 : 变量类型 = 变量值 or val 变量名 = 变量值
-
代码案例 ☁️
object VariableByUse { def main(args: Array[String]): Unit = { // 定义变量的方式 : // (1) 定义时指定类型 val str : String = "hello" // (2) 根据值自动判断类型 val num = 1.2 val isMan = true println(s"str = ${str} , num = ${num} , isMan = ${isMan}") } }
Scala 变量的使用说明 ⭐️
-
声明变量时变量的类型可以省略 (编译器会根据变量的值推导变量的类型)
-
☀️Scala 是强类型语言, 变量的类型确定后 就不可以修改
-
❤️在声明/定义一个变量的时候,可以使用var或者val来修饰
- 1️⃣val修饰的变量不可以改变
- 2️⃣var修饰的变量可以改变
package variable /** * 测试 val 和 var 的性质 * @author 王天赐 * @create 2019-07-12 12:02 */ object ValAndVarTest { def main(args: Array[String]): Unit = { // 1.val修饰的变量不可变 // 2.var修饰的变量可变 // 首先测试基础变量 var v01 = 12 val v02 = 12 v01 = 22 // v02 = 22 显然这里是不可以的 编译器直接会报错 // 测试对象 var stu01 = new Student() val stu02 = new Student() stu01 = new Student() // stu02 = new Student() 这里编译器也报错了 ,显然也是不可以的 } } class Student{ var name = "李白" var age = 10 }
-
scala 的设计者为什么要设计 var 和 val ❓
- 在实际的编程过程中我们一般都是改变一个对象的属性值,或者读取属性,基本很少对这个对象本身进行改变 , 所以当我们不需要改变对象本身的时候 最好使用 val
- 其次 因为val没有线程安全问题 所以效率高 scala的设计者也推荐我们使用val
- 当然 : 如果对象需要改变,我们还是使用 var
-
程序中 + 号的作用
- 当左右都是数值时 做加法运算
- 左右都是字符串时 做拼接运算
Scala 中的数据类型 ⭐️⭐️
-
Scala 和 Java 有相同的数据类型 , 在 Scala 中数据类型都是对象 也就是说 scala没有原生的类型
-
Scala数据类型分为两大类 AnyVal(值类型) 和 AnyRef(引用类型), 注意:不管是AnyVal还是AnyRef 都是对象
-
Scala 数据类型体系
- SubType 继承
- implicit Conversion 隐式转换
[外链图片转存失败(img-MATsaJUv-1562939781166)(image/1562906735401.png)]
-
代码案例
package variable import scala.collection.immutable.StringOps import java.util.ArrayList /** * Scala 的基本类型 * * @author 王天赐 * @create 2019-07-12 12:46 */ object DataType { def main(args: Array[String]): Unit = { /* 1. Any * AnyVal * AnyRef 2.AnyVal * Byte -> Short -> Int -> Long -> Float -> Double * Boolean , Char , StringOps , Unit 3.AnyRef * Scala 集合 * 所有的java类 * 其他的 Scala 类 * Null 4. Nothing */ // 1.AnyVal val byteVal : Byte = 1 val shortVal : Short = 12 val intVal : Int = 22 val longVal : Long = 22L val floatVal : Float = 1.22f val doubleVal : Double = 1.33 val boolValue : Boolean = true val strOps: StringOps = "Hello" val empty : Unit = () // Unit 只有一个值 () // 2. AnyRef val nul : Null = null // 注意 Null 类型只有一个值 null // java class val math : ArrayList[String] = new ArrayList[String]() // scala 的集合 val set : Set[String] = Set("hello" , "hahha") // scala 的对象 val student : Student = new Student() } } class Student{ }
-
⭐️ Scala 类型列表
数据类型 描述 Byte 8位有符号补码整数。数值区间为 -128 到 127 Short 16位有符号补码整数。数值区间为 -32768 到 32767 Int 32位有符号补码整数。数值区间为 -2147483648 到 2147483647 Long 64位有符号补码整数。数值区间为 -9223372036854775808 到 9223372036854775807 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)的基类 -
⭐️ 总结 :
- Any 类是 所有类的父类 ! 注意 是scala出现的所有类 相当于 Java 中的Object
- Scala 中一切都是对象 ,分为两大类 : AnyVal(值类型) , AnyRef(引用类型) 他们都是 Any 的子类
- ❗️ Null 类型时scala的特别类型, 它只有一个值 null ,他是 bottom class (底层类) 是所有 AnyRef (引用类) 的子类
- ❗️ Nothing 类型也是 bottom class 它是所有类的子类, 在开发中通常可以将 Nothing 类型的值返回给任意类型的变量或者函数 一般抛出异常的时候使用的比较多
- ⭐️特别注意 : String类型不是值(AnyRef)类型 它是值类型
AnyVal - 整数类型 ⭐️⭐️
-
类型列表
Byte [1] 8位有符号补码整数。数值区间为 -128 到 127 Short [2] 16位有符号补码整数。数值区间为 -32768 到 32767 Int [4] 32位有符号补码整数。数值区间为 -2147483648 到 2147483647 Long [8] 64位有符号补码整数。数值区间为 -9223372036854775808 到 9223372036854775807 = 2的(64-1)次方-1 -
⭐️❤️ 整型的使用细节
- Scala 各个整数类型有固定的表数范围和字段长度,不受具体的系统的影响,以保证Scala程序的可移植性
- Scala 整型默认是 Int 类型, 需要声明 Long 类型的需要在数值后面加 ‘L’
package variable /** * 测试整数类型的使用 * @author 王天赐 * @create 2019-07-12 15:27 */ object IntegerType { def main(args: Array[String]): Unit = { var i = 1 // 默认是 Int var j = 10L // 指定是 Long 类型的 var e = 9999999999999L // 数值较大时需要指定是 Long类型的 println(i.getClass) // 结果是 int println(j.getClass) // 结果是 long var b : Byte = 122 var s : Short = 11 println(b.getClass) // byte println(s.getClass) // short } }
-
⭐️补充 : 如何打印出变量的类型 ? => 使用 getClass
var i = 1 // 默认是 Int var j = 10L // 指定是 Long 类型的 var e = 9999999999999L // 数值较大时需要指定是 Long类型的 println(i.getClass) // 结果是 int
AnyVal - 浮点类型 ⭐️⭐️
- 类型列表
Float [4] | 32 位, IEEE 754标准的单精度浮点数 |
---|---|
Double [8] | 64 位 IEEE 754标准的双精度浮点数 |
-
⭐️❤️浮点型变量使用细节
-
Scala 各个浮点型类型有固定的表数范围和字段长度,不受具体的系统的影响,以保证Scala程序的可移植性
-
Scala的浮点型常量默认为Double型,声明Float型常量,须后加’f’或’F’。
package variable /** * 浮点类型的基本使用 * @author 王天赐 * @create 2019-07-12 15:43 */ object FloatType { def main(args: Array[String]): Unit = { // 默认是 double 类型 var f1 : Float = 1.2f //需要加上 F , Double精度比Float高,无法自动转换 var f2 = 1.2 // 会自动根据数据推断类型 默认浮点数是 Double 类型 var f3 : Double = 1.4f // Double 精度大于 Float 自动转换是 ok的 // 打印数据类型 println(f1.getClass) println(f2.getClass) println(f3.getClass) } } // 结果 : float double double
-
浮点型常量的两种表示形式
- 十进制形式: 5.12 , 512.0f (.512 这种也是可以的)
- 科学计数法 : 5.12e2 = 5.12 ∗ * ∗ 1 0 2 10^2 102
-
通常情况下,应该使用Double型,因为它比Float型更精确(小数点后大致7位)
-
AnyVal - 字符类型 ⭐️⭐️
-
基本介绍
字符类型可以表示单个字符,字符类型是Char, 16位无符号Unicode字符(2个字节), 区间值为 U+0000 到 U+FFFF
-
⭐️❤️ 字符类型使用细节
- 可以直接给Char赋一个整数,然后输出时,会按照对应的unicode 字符输出 [’\u0061’ 97]
- Char类型是可以进行运算的,相当于一个整数,因为它都对应有Unicode码.
- ⭐️1️⃣ 当把一个计算结果赋值给一个变量的时候 编译器会对这个计算结果进行类型转换和范围的判定 (会看范围+类型)
- ⭐️2️⃣ 当把一个字面量的值赋给一个变量的时候 编译器只会对这个字面量进行范围的判定 (只会看范围)
package variable /** * 字符类型的数据使用 * @author 王天赐 * @create 2019-07-12 16:06 */ object CharType { def main(args: Array[String]): Unit = { var c1 = 'a' var c2 = '\t' var c3 = '你' var c4 : Char = 97 println(c1) println(c2) println(c3) println(c4) // 1. 当把一个计算结果赋值给一个变量的时候 编译器会对这个计算结果进行类型转换和范围的判定 (会看范围+类型) // 2. 当把一个字面量的值赋给一个变量的时候 编译器只会对这个字面量进行范围的判定 (只会看范围) // var c5 : Char = 'a' + 1 // var c6 : Char = 91 + 1 var c7 : Char = 94 } } // 结果 a 你 a
AnyVal - 布尔类型 ⭐️
- 基本介绍
- 布尔类型也叫Boolean类型,Booolean类型数据只允许取值true和false
- boolean类型占1个字节。
- boolean 类型适于逻辑运算,一般用于程序流程控制
Unit类型、Null类型和 Nothing类型 ⭐️⭐️
-
类型列表
Unit 表示无值,和其他语言中void等同。用作不返回任何结果的方法的结果类型。Unit只有一个实例值,写成()。 Null null , Null 类型只有一个实例值 null Nothing ⭐️Nothing类型在Scala的类层级的最低端;它是任何其他类型的子类型。当一个函数,我们确定没有正常的返回值,可以用Nothing 来指定返回类型,这样有一个好处,就是我们可以把返回的值(异常)赋给其它的函数或者变量(兼容性) -
⭐️❤️ 使用细节
- Null类只有一个实例对象,null,类似于Java中的null引用。null可以赋值给任意引用类型(AnyRef),但是不能赋值给值类型(AnyVal: 比如 Int, Float, Char, Boolean, Long, Double, Byte, Short)
- Unit类型用来标识过程,也就是没有明确返回值的函数。由此可见,Unit类似于Java里的void。Unit只有一个实例,(),这个实例也没有实质的意义
- Nothing,可以作为没有正常返回值的方法的返回类型,非常直观的告诉你这个方法不会正常返回,而且由于Nothing是其他任意类型的子类,他还能跟要求返回值的方法兼容
package variable /** * 测试 Unit Null Nothing 类型的使用细节 * @author 王天赐 * @create 2019-07-12 16:36 */ object EmptyType { def main(args: Array[String]): Unit = { // 1.Null 类只有一个实例对象, null 类似于Java类中的 null // null 可以赋值给任何引用类型(AnyRef), 但是不能赋值给值类型(AnyVal) 比如 Int , Float .. // 特别注意 : String类型不是值(AnyRef)类型 它是值类型 val str: String = null val list: List[String] = null // 2.Unit类型用来标识过程,也就是没有明确返回值的函数。 // 由此可见,Unit类似于Java里的void。Unit只有一个实例,(),这个实例也没有实质的意义 def num(a : Int , b : Int): Unit ={ println(a + b) } // Nothing,可以作为没有正常返回值的方法的返回类型,非常直观的告诉你这个方法不会正常返回, // 而且由于Nothing是其他任意类型的子类,他还能跟要求返回值的方法兼容 } }
Scala - 值类型转换 ⭐️⭐️⭐️
-
值类型隐式转换
-
介绍
当Scala程序在进行赋值或者运算时,精度小的类型自动转换为精度大的数据类型,这个就是自动类型转换(隐式转换)
-
数据类型大小按精度排序 : Byte -> Short -> Int -> Long -> Float -> Double
-
☁️ 代码案例 :
package variable /** * 测试 值类型的隐式转换 * @author 王天赐 * @create 2019-07-12 17:45 */ object TypeImplicitConversion { def main(args: Array[String]): Unit = { // 隐式转换规则 : Byte -> Short -> Int -> Long -> Float -> Double // 按精度 从低到高可以自动转换 从高到低无法自动转换 var v01 : Byte = 10 println(v01.getClass) var v02 : Int = v01 println(v02.getClass) // var v03 : Short = v02 // 注意 此时 v02 是 Int 类型的 高精度类型无法隐式转换成低精度 所以会报错 // Byte Short 和 Char 之间不会相互转换 var v03 : Short = 10 // 注意 : 当 Byte , Short Char 这三个类型进行计算的时候 会转换成 Int 类型 // 所以下面的代码 中 v01 + v03 的结果是 Int 类型 无法赋值给 Shrot 编译器会报错 // var v04 : Short = v01 + v03 // 当我将变量类型改为 Int 代码就不会报错 var v05 : Int = v01 + v03 } }
-
-
⭐️❤️ 自动类型转换细节说明
- 有多种类型的数据混合运算时,系统首先自动将所有数据转换成容量最大的那种数据类型,然后再进行计算。
- 当我们把精度(容量)大 的数据类型赋值给精度(容量)小 的数据类型时,就会报错,反之就会进行自动类型转换。 (原因其实很简单 :高精度类型向低精度转换时可能会损失精度,为了避免这个问题 所以编译器不允许高精度的变量向低精度转换)
- (byte, short) 和 char之间不会相互自动转换。
- ❗️ byte,short,char 他们三者可以计算,在计算时首先转换为int类型
- 自动提升原则: 表达式结果的类型自动提升为 操作数中最大的类型
-
强制类型转换
-
介绍
自动类型转换的逆过程,将容量大的数据类型转换为容量小的数据类型。使用时要加上强制转函数,但可能造成精度降低或溢出,格外要注意。
-
⭐️❤️ 强制类型转换细节说明
- 当进行数据的 从 大——>小 (指精度),就需要使用到强制转换
- 强转符号只针对于最近的操作数有效,往往会使用小括号提升优先级
- Char类型可以保存 Int的常量值,但不能保存Int的变量值,需要强转 ❓
- Byte和Short类型在进行运算时,当做Int类型处理。
-
☁️ 代码案例 :
package variable /** * 强制类型转换 * @author 王天赐 * @create 2019-07-12 21:11 */ object ForcedTypeConversion { def main(args: Array[String]): Unit = { var v01 : Byte = 1 var v02 : Short = 2 var v03 : Int = 3 var v04 : Float = 1.2f // Short -> Byte v01 = v02.toByte // Int -> Byte v01 = v03.toByte // 复杂一点的转换一般用 括号来提升优先级 var v05 : Byte = (1.2.toInt + 2.toFloat).toByte // Char类型可以保存 Int的常量值,但不能保存Int的变量值,需要强转 // var c01 : Char = v03 // 这里会报错 因为v03 是有类型的 赋值时需要考虑 类型和范围 相当于 Int -> Char var c02 : Char = 12 // 这个不会报错 因为单纯常量(字面量) 赋值时是不考虑值的类型而只考虑范围 } }
-
Scala - 值类型和String类型的转换 ⭐️⭐️⭐️
-
介绍
在程序开发中,我们经常需要将基本数据类型转成String 类型。
或者将String类型转成基本数据类型。 -
☁️ 代码案例
package variable /** * @author 王天赐 * @create 2019-07-12 21:25 */ object StringTypeConversion { def main(args: Array[String]): Unit = { var str01 = "hello" var str02 = "123" var str03 = "11.2" var str04 = "1.2e2" var v01 = 1 var v02 = 2.2 // 基本类型 => String var str05 = v01 + "" var str06 = v02 + "" println(s"str05 = ${str05} , str06 = ${str06}") // String => 基本类型 // var v03 = str01.toInt // 如果字符串不是整型或者浮点型的话无法成功 var v05 = str02.toInt var v06 = str03.toDouble var v07 = str04.toDouble println("v05 = " + v05) println("v06 = " + v06) println("v07 = " + v07) } } // 输出结果 str05 = 1 , str06 = 2.2 v05 = 123 v06 = 11.2 v07 = 120.0