一、基础语法学习
1.1 声明变量
1.1.1 语法格式
在 Scala 中,可以使用 val 或者 var 关键字来定义变量,语法格式如下:
val/var 变量标识:变量类型 = 初始值
注意:
- val 定义的是 不可重新赋值的变量,不可变。 不是 java 中 final 的意思。Scala 也有 final,在 Scala 中 final 表示数值不可变以及不可被覆写。val 仅仅是数值不变,可以被复写。
- var 定义的是 可重新赋值的变量,可变。
- Scala 中定义变量类型写在变量名后面。
- Scala 的语句最后不需要添加分号。
- Scala 中类型是 首字母大写的。
1.1.2 在解释器中定义一个变量
示例:定义一个变量保存一个人的名字 “Amo”
步骤:
- 打开 Scala 解释器
- 定义一个字符串类型的变量用来保存名字
参考代码
scala> val name:String = "Amo" name: String = Amo
1.1.3 val 和 var 变量
示例1
给名字变量进行重新赋值为 Jerry,观察其运行结果
示例2
使用 var
重新定义变量来保存名字 “Paul”,并尝试重新赋值为 “Ben”,观察其运行结果:
scala> var name:String = "Paul" name: String = Paul scala> name = "Ben" name: String = Ben
优先使用 val 定义变量,如果变量需要被重新赋值,才使用 var。
1.1.4 使用类型推断来定义变量
Scala 的语法要比 Java 简洁,我们可以使用一种更简洁的方式来定义变量。Scala 是强类型语言,千万不要被它省略类型所迷惑。它是可以省略类型,不代表变量没有类型。
示例1
使用更简洁的语法定义一个变量保存一个人的名字 “Amo”
参考代码
scala> val name = "Amo" name: String = Amo
Scala 可以自动根据变量的值来自动推断变量的类型,这样编写代码更加简洁。
1.1.5 惰性赋值
什么时候用到,什么时候被加载的内存中。 在企业的大数据开发中,有时候会编写非常复杂的 SQL 语句,这些 SQL 语句可能有几百行甚至上千行。这些 SQL 语句,如果直接加载到 JVM 中,会有很大的内存开销。如何解决?当有一些变量保存的数据较大时,但是不需要马上加载到 JVM 内存。可以使用 惰性赋值 来提高效率。语法格式:
lazy val 变量名 = 表达式
注意:var 不可以用 lazy
1.2 字符串
Scala 提供多种定义字符串的方式,将来我们可以根据需要来选择最方便的定义方式。使用双引号、使用插值表达式、使用三引号。
1.2.1 使用双引号
语法
val/var 变量名 = "字符串"
示例: 有一个人的名字叫 “Amo”,请打印他的名字以及名字的长度。
参考代码
scala> val name:String = "Amo" name: String = Amo scala> println(name + name.length) Amo3
1.2.2 使用插值表达式
Scala 中,可以使用插值表达式来定义字符串,有效避免大量字符串的拼接。语法:
val/var 变量名 = s"${变量/表达式}字符串"
- 在定义字符串之前添加 s
- 在字符串中,可以使用 ${} 来引用变量或者编写表达式
示例: 请定义若干个变量,分别保存:“Amo”、18、“male”,定义一个字符串,保存这些信息。打印输出:name=Amo, age=18, sex=male
参考代码
scala> val name = "Amo" name: String = Amo scala> val age = 18 age: Int = 18 scala> val sex = "male" sex: String = male scala> println(s"name=${name},age=${age},sex=${sex}") name=Amo,age=18,sex=male
1.2.3 使用三引号
如果有大段的文本需要保存,就可以使用三引号来定义字符串。例如:保存一大段的 SQL 语句。三个引号中间的所有字符串都将作为字符串的值。语法:
val/var 变量名 = """字符串1 字符串2"""
示例: 定义一个字符串,保存以下 SQL 语句。
scala> val sql = """ | create table course( | cid string, | cname string, | tid string) | clustered by(cid) into 3 buckets | row format delimited fields terminated by '\t'; | """ sql: String = " create table course( cid string, cname string, tid string) clustered by(cid) into 3 buckets row format delimited fields terminated by '\t'; " scala> println(sql) create table course( cid string, cname string, tid string) clustered by(cid) into 3 buckets row format delimited fields terminated by '\t';
但是要注意一点,三引号字符串不要出现重复,比如 ""'' aaa """ bbb """
。因为,Scala 编译器,从第一个三引号开始,到第二个三引号结束,算一个完整的字符串,后面的就是多出来的语法错误的内容。
1.3 数据类型与操作符
Scala 中的类型以及操作符绝大多数和 Java 一样,我们主要来学习,与 Java 不一样的一些用法,Scala 类型的继承体系。
1.3.1 数据类型
基础类型 | 类型说明 |
Byte | 8位带符号整数 |
Short | 16位带符号整数 |
Int | 32位带符号整数 |
Long | 64位带符号整数 |
Char | 16位无符号Unicode字符 |
String | Char类型的序列(字符串) |
Float | 32位单精度浮点数 |
Double | 64位双精度浮点数 |
Boolean | true或false |
Scala 类型与 Java 的区别:
- Scala 中所有的类型都使用 大写字母 开头。
- 整型使用 Int 而不是 Integer。
- Scala 中定义变量可以不写类型,让 Scala 编译器自动推断。
1.3.2 运算符
类别 | 操作符 |
算术运算符 | +、-、*、/、%(加减乘除和取模) |
关系运算符 | >、<、==、!=、>=、<= |
逻辑运算符 | &&、||、! |
位运算符 | &、||、^、<<、>> |
Scala 中的运算符, 基本上和 Java 一样, 除了:
- Scala 中没有,++、-- 运算符
- 与 Java 不一样,在 Scala 中,想要比较值是否相同,就用
==
即可。 在 Scala 中==
是很智能的。 如果对象为 NULL 会自动判断空的情况, 如果对象不为空会自动判断对象的值是否相等。想要比较内存地址,使用.eq
方法。
示例: 有一个字符串"abc",再创建第二个字符串,值为:在第一个字符串后拼接一个空字符串。然后使用比较这两个字符串是否相等、再查看它们的引用值是否相等。
参考代码
scala> val str1 = "abc" str1: String = abc scala> val str2 = str1 + "" str2: String = abc scala> str1==str2 res4: Boolean = true scala> str1.eq(str2) res5: Boolean = false
1.3.3 Scala 类型层次结构
所有的类型都是从 Any 继承了, 也就是我们 Scala 是一种单根继承体系。
类型 | 说明 |
Any | 所有类型 的父类,它有两个子类 AnyRef 与 AnyVal |
AnyVal | 所有数值类型 的父类 |
AnyRef | 所有对象类型(引用类型)的父类 (String 本质就是 Char 数组,也是引用类型哦) |
Unit | 表示空,Unit 是 AnyVal 的子类,它只有一个的实例{% em %}() {% endem %} 它类似于 Java 中的 void,但 Scala 要比 Java 更加面向对象,Unit 本身也是一个类哦,当返回值为空的时候,返回的就是 Unit,Unit 的实例就是一个括号(). 这个对象用来做空返回值的时候用 |
Null | Null 也就是 AnyRef 的子类,也就是说它是所有引用类型的子类。它的实例是{% em %}** null **{% endem %} 可以将null赋值给任何引用对象类型. 真的是空,表示的是 引用类型 指针指向的内存地址不存在或者不指向内存区域。 |
Nothing | 所有类型的 子类 不能直接创建该类型实例,某个方法抛出异常时,返回的就是 Nothing 类型,因为 Nothing 是所有类的子类,那么它可以赋值为任何类型 |
问题: 以下代码是否有问题?
val b:Int = null
Scala 会解释报错:Null 类型并不能转换为 Int 类型,说明 Null 类型并不是 Int 类型的子类,也就是不是数值类型 AnyVal 的子类。
1.4 条件表达式
条件表达式就是 if 表达式,if 表达式可以根据给定的条件是否满足,根据条件的结果(真或假)决定执行对应的操作。Scala 条件表达式的语法和 Java 一样。
1.4.1 有返回值的 if
与 Java 不一样的是:
- 在 Scala 中,条件表达式也是有返回值的。
- 在 Scala 中,没有三元表达式,可以使用 if 表达式替代三元表达式。
示例: 定义一个变量 sex,再定义一个 result 变量,如果 sex 等于 “male”,result 等于 1,否则 result 等于 0。
参考代码
scala> val sex = "male" sex: String = male scala> val result = if sex == "male" 1 else 0 <console>:1: error: '(' expected but identifier found. val result = if sex == "male" 1 else 0 ^ scala> val result = if(sex == "male") 1 else 0 result: Int = 1
1.4.2 块表达式
- Scala 中,使用 {} 表示一个块表达式。
- 和 if 表达式一样,块表达式也是有值的。
- 值就是最后一个表达式的值(因为 Scala 中没有 return 语句)
问题: 请问以下代码,变量 a 的值是什么?
scala> val a = { | println(1+1) | 1 + 1 | } 2 a: Int = 2