Scala Language
Scala语言
Scala是一门多范式的编程语言,能够以一种优雅的方式来解决现实问题,同时支持面向对象和面向函数的编程风格。虽然它是强静态类型的编程语言,但是它强大的类型推断能力,使其看起来就像是一个动态编程语言。Scala语言最终会被编译成java字节码文件,可以和JVM无缝集成,并且可以使用Scala调用Java的代码库。Scala编程语言除了自身的特性以外,目前比较流行的Spark计算框架也是使用Scala语言编写。Spark 和 Scala 能够紧密集成,例如,使用Scala语言操作大数据集合时,用户可以像是在操作本地数据集那样简单操作Spark上的分布式数据集-RDD(这个概念是Spark 批处理的核心术语),继而简化大数据集的处理难度,简化开发步骤。
特点
- 面向对象编程语言 传递数据 | 数据建模
- 面向函数式编程语言 专门为数据而生的语言 传递函数 | 数据分析计算
- 强大的集合计算能力 (后续课程介绍)
因为现在主流大数据计算框架均对Scala编程支持比较友好,例如:Kafka.0.11.0_2.11.tar.gz、Spark使用Scala,导致使用Scala语言可以高效实现数据分析处理。
编程指南:https://docs.scala-lang.org/tour/tour-of-scala.html
环境安装
下载对应的Scala版本:https://www.scala-lang.org/download/2.11.12.html
Windows版本安装
- 点击
scala-2.11.12.msi
双击msi文件安装 - 配置Scala的环境变量SCALA_HOME变量
SCALA_HOME=C:\Program Files (x86)\scala
PATH=C:\Program Files\Java\jdk1.8.0_161/bin;C:\Program Files (x86)\scala/bin;
- 打开Window窗口
C:\Users\Administrator>scala
Welcome to Scala 2.11.12 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_161).
Type in expressions for evaluation. Or try :help.
scala>
CentOS安装
- 下载
scala-2.11.12.rpm
- 安装配置Scala
[root@CentOS ~]# rpm -ivh scala-2.11.12.rpm
Preparing... ########################################### [100%]
1:scala ########################################### [100%]
[root@CentOS ~]# scala
Welcome to Scala 2.11.12 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_171).
Type in expressions for evaluation. Or try :help.
scala>
IDEA集成Scala开发环境
在File>Setting>Plugins点击 install pluginfromdisk
选项,选择 scala-intellij-bin-2018.2.11.zip
安装成功后,重启IDEA
Scala变量
Scala语言没有基本数据类型,这一点和Java语言不同,在Scala中一切皆对象,以下是Scala语言中的常见类型和类型间的继承关系:
Scala是一门纯粹的面向对象编程语言,该语言没有基本类型。所有值类型都是AnyVal的子类,所有对象类型都是AnyRef的子类。一般所有的AnyVal类型都有字面值,所有AnyRef类型的默认值都是Null
变量定义
Scala语言是一种可以做类型自动推断的强类型的编程语言。变量的类型可以通过编译器在编译时自动推断出最终类型,因此在Scala中声明一个变量,需要告知编译器该变量的值是常量还是变量,例如:声明一个变量使用var关键字,声明一个常量使用val关键字。Scala语言的变量声明语法如下:
[var|val] 变量名[:变量类型]=变量值[:类型]
scala> var i:Int=1:Int
i: Int = 1
scala> var i=1:Int
i: Int = 1
scala> var i=1
i: Int = 1
scala> var j=1
j: Int = 1
scala> var j=1:Byte
j: Byte = 1
scala> var j:Byte=1
j: Byte = 1
由于Scala语言具有强大的类型推断能力,因此在声明变量的时候,如果类型不存在歧义,一般可以省略
asInstanceOf
当类型兼容时,使用asInstanceOf[目标类型]强转,例如:Long转换Int、Double转换为Float,大->小
类型兼容
scala> var j:Byte=1
j: Byte = 1
scala> var i=10
i: Int = 10
scala> var j:Byte=0
j: Byte = 0
scala> j=i
<console>:13: error: type mismatch;
found : Int
required: Byte
scala> i=j
i: Int = 0
scala> j=i.asInstanceOf[Byte]
j: Byte = 0
j=i
^
toXxx类型
将字符串的字面值尝试转换为值类型
scala> var i=0
i: Int = 0
scala> var j="123"
j: String = 123
scala> i=j
<console>:13: error: type mismatch;
found : String
required: Int
i=j
^
scala> i=j.asInstanceOf[Int]
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integ
er
at scala.runtime.BoxesRunTime.unboxToInt(BoxesRunTime.java:101)
scala> i=j.toInt
i: Int = 123
... 32 elided
元组
由多个元素组成的复合变量称为元组,元组的值都是只读的,元组的元素最多不可以超过22个
scala> var t=(1,"zs",false)
t: (Int, String, Boolean) = (1,zs,false)
scala> t._2
res0: String = zs
scala> t._2="lisi"
<console>:12: error: reassignment to val
t._2="lisi"
^
数组
scala> var a=new Array[Int](4)
a: Array[Int] = Array(0, 0, 0, 0)
scala> var a=Array(1,2,3,4)
a: Array[Int] = Array(1, 2, 3, 4)
scala> a(0)= -1
scala> a
res4: Array[Int] = Array(-1, 2, 3, 4)
scala> a.length
res5: Int = 4
scala> a.size
res6: Int = 4
Unit
Unit是一种特殊的值类型,该类型是一个空的元组,通常作为函数的返回值,等价于Java中的void关键字
scala> var u:Unit=()
u: Unit = ()
分支循环
if条件分支
语法
if(条件){
}else if(条件){
}
...
else{
}
var a=28
if(a<=10){
println("child")
}else if(a<=20){
println("boy|girl")
}else{
println("man|woman")
}
和Java不同,if 可以将代码块的返回值返回给一个变量
var a=28
var result=if(a<=10){
"child"
}else if(a<=20){
"boy|girl"
}else{
"man|woman"
}
println(s"结果:${result}")
while、do-while
while(条件){
//循环体
}
在scala语言中while和do-while没有continue和break关键字
var a=5
while (a>0){
print("\t"+a)
a -= 1
}
---
do{
print("\t"+a)
a -= 1
}while(a>0)
Breaks
Scala 语言中默认没有 break 语句,但是在 Scala 2.8 版本以后可以使用另外一种方式来实现 break 语句功能。在循环中使用 break.break() 语句,当程序执行到该语句时,就会中断循环并执行循环体之后的代码块
scala> import scala.util.control.Breaks
import scala.util.control.Breaks
scala> var a=10
a: Int = 10
scala> var break=new Breaks
break: scala.util.control.Breaks = scala.util.control.Breaks@17eeaaf
scala> break.breakable({
| do{
| print("\t"+a)
| a -= 1
| if(a<=5){
| break.break()
| }
| }while(a>0)
| })
10 9 8 7 6
for循环(重点)
- 迭代遍历数组
scala> var array=Array(1,2,3,4)
array: Array[Int] = Array(1, 2, 3, 4)
scala> for(item <- array){
print(item+"\t")}
1 2 3 4
- 通过下标遍历数组
scala> var array=Array(1,2,3,4)
array: Array[Int] = Array(1, 2, 3, 4)
scala> for(i <- 0 until array.length) {
| print(array(i))
| }
- for可使用多个循环因子
scala> for(i <- 1 to 9;j <- 1 to i){
| print(s"${i}*${j} ="+i*j+"\t")
| if(i==j){
| println()
| }
| }
1*1 =1
2*1 =2 2*2 =4
3*1 =3 3*2 =6 3*3 =9
4*1 =4 4*2 =8 4*3 =12 4*4 =16
5*1 =5 5*2 =10 5*3 =15 5*4 =20 5*5 =25
6*1 =6 6*2 =12 6*3 =18 6*4 =24 6*5 =30 6*6 =36
7*1 =7 7*2 =14 7*3 =21 7*4 =28 7*5 =35 7*6 =42 7*7 =49
8*1 =8 8*2 =16 8*3 =24 8*4 =32 8*5 =40 8*6 =48 8*7 =56 8*8 =64
9*1 =9 9*2 =18 9*3 =27 9*4 =36 9*5 =45 9*6 =54 9*7 =63 9*8 =72 9*9 =81
- for和if的使用
scala> for(i<- 0 to 10;if(i%2==0)){
| print(i+"\t")
| }
0 2 4 6 8 10
- for和yield关键字实现元素的提取、创建子集(重点)
scala> var a=Array(1,2,3,4,5)
a: Array[Int] = Array(1, 2, 3, 4, 5)
scala> var res=for(item<-a) yield item*item
res: Array[Int] = Array(1, 4, 9, 16, 25)
match-case(模式匹配)
在Scala语言中剔除了Java中的switch-case
语句,提供了match-case
替代方案,该方案不仅可以按照值匹配,还可以按照类型、以及值的结构(数组匹配、元组匹配、case-class匹配等)
- 值匹配
var a=Array(1,2,3)
var i=a(new Random().nextInt(3))
var res= i match {
case 1 => "one"
case 2 => "two"
case 3 => "three"
case default => null
}
println(res)
- 类型匹配
var a=Array(100,"张三",true,new Date())
var i=a(new Random().nextInt(4))
var res= i match {
case x:Int => s"age:${x}"
case x:String => s"name:${x}"
case x:Boolean => s"sex:${x}"
case _ => "啥都不是"
}
println(res)
注意:
_
表示默认匹配,等价于default
关键字
函数 | 方法
def 方法名(参数1:参数类型,...):返回值类型={
//代码块的最后一行, 默认是方法的返回值,一般可以省略return关键字
}
√标准函数
scala> def sum(x:Int,y:Int):Int={
| x+y
| }
sum: (x: Int, y: Int)Int
一般情况下,如果函数体的最后一行作为函数的返回值,一般可以省略函数的返回值类型,例如:
scala> def sum(x:Int,y:Int)={
| x+y
| }
sum: (x: Int, y: Int)Int
scala> def sum(x:Int,y:Int):Int={
| return x+y
| }
sum: (x: Int, y: Int)Int
如果函数体中有return语句,函数不能省略返回值类型
scala> def sum(x:Int,y:Int)={
| return x+y
| }
<console>:12: error: method sum has return statement; needs result type
return x+y
^
可变长参数
scala> def sum(values:Int*):Int={
| var total=0
| for( i<- values) total += i
| total
| }
sum: (values: Int*)Int
scala> sum(1,2,3,4,5)
res9: Int = 15
scala> def sayHi(msg:String,names:String*):Unit={
| for(name <- names){
| println(msg+"\t"+name)
| }
| }
sayHi: (msg: String, names: String*)Unit
scala> sayHi("Hello","zs")
Hello zs
可变长参数必须放置在最后一位
scala> def sayHi