为什么要学习Scala?
目前Spark是新一代的内存型大数据计算框架,是目前大数据技术生态圈中非常主流的一门技术。
而Spark就是使用Scala编写,包括Kafka早期底层也是用Scala写的,因此为了更好的学习Spark,看懂Spark源码,那就需要掌握Scala这门语言。
因此可以说Spark的兴起带动了Scala的兴旺。
静态类型语言和动态类型语言区别
静态类型语言是在还没运行期间就提醒哪里有错误,这个是在编译期间。
动态类型语言是在运行的时候才告诉你哪里错了,这个是在运行期间。
Scala是什么?
Scala是一门多范式语言(函数式编程和面向对象编程),且是一门静态类型语言,这门语言是产生自瑞士的洛桑联邦理工学院,Scala是可扩展语言(Scalable Language)的缩写。
Scala的作者是马丁奥德斯基,这个作者还是JDK5.0和JDK8.0编译器的编写者,因此我们可以看到在JDK5.0和8.0的很多内容和Scala似乎有重合之处,比如泛型、for循环增强、自动类型转换、Lambda表达式等都是从Scala引入的特性。
官网:https://www.scala-lang.org/
在Scala,一切都是对象,数字、符号都是对象
Scala和Java的关系
Scala是运行在JVM虚拟机上的
Scala可以调用Java的类库,如Scala的数组
Scala编译之后是class文件
Scala有自己的编译器,特定的语法使用Java是编译不过的
Scala的部分语法是可以使用Java编译器进行编译
面向XX编程解释
面向过程编程:看重业务步骤
面向对象编程:业务修改成对象之间的关系进行处理
面向接口编程:业务抽象成接口规则
面向切面编程:根据业务逻辑进行动态组织,假如从这里过的都要记录下姓名
面向命令式编程:解决问题的步骤
面向函数式编程:关系数据的映射、数学逻辑的运算
特点
1.运行在JVM和Javascript之上的语言
Scala不单是使用了JVM的高性能以及最优化性,连Java丰富的工具和类生态系统也为其所用,不过Scala并不只是运行在JVM之上,Scala-Js在让其在JavaScript的世界也可以运行。
Scala-js官网:http://www.scala-js.org/
2.静态类型语言
在Scala中静态类型是构建健壮应用系统的一个工具,Scala修正了Java类型系统中的一些缺陷,此外通过类型推导也免除了大量的冗余代码
3.混合式编程
Scala支持面向对象编程,Scala引入特质(trait),改进了Java的对象模型,trait能使用混合结构,简洁的实现新的类型,在Scala一切都是对象,符号、数组都是对象。
Scala完全支持函数式编程,函数式编程已经视为解决并发大数据以及代码正确性问题的最佳工具,使用不可变值,被使用一等公民的函数,无副作用的函数,高阶函数及函数集合。
4.复杂的类型系统
Scala对Java类型系统进行了扩展,提供了更灵活的泛型以及一些有助于提高代码的改进。
5.简洁优雅灵活的语法
Java冗长的表达式不见了。
6.可扩展框架
能够编写出简短的解释性脚本
使用特质实现的混合结构
HelloWorld.scala
Scala执行流程图
Scala数据类型
小结
在Scala中所有类型所有一个统一的引用类型Any,这是Scala的特点。
Null是所有引用类型的子类型
Nothing是有类型的子类型,通常作为没有正常返回值的返回类型
Unit相当于Java的void
Nil是空集合的意思
Scala没有++、--操作符,用+=、-=。如:var i = 0; i += 3
在Scala中 _ 是通用符,相当于Java的*,也可以作为替代符,用处很广
Scala不支持三元表达式
Scala可以在任意的地方使用import,Java只能规定在类的上方
Scala声明变量
条件判断表达式
块表达式
循环
for
while
方法和函数
异常
数据结构
Scala同时支持可变和不可变集合,可以安全并发的访问
可变包:scala.collection.mutable
不可变包:scala.collection.immutable
可变就是定义了这个集合,还可以对元素进行增删改
不可变就是定义了这个集合,就不可以对这个集合的元素进行增删改,这个可以用于并发的时候,不想别人修改你的容器内容
Scala优先采用不可变的集合(安全),所以Scala默认是导入scala.collection.immutable,要使用可变集合,就要自己去导入可变集合的包
集合主要由三大类:序列、集、映射
所有的集合都扩展自Iterable特质。
集合所有集合类,Scala都提供了可变和不可变的版本。
每个Scala集合特质或类都有一个Apply的伴生对象(类似Java静态方法),这个Apply方法可以用来构建该集合的实体,这样的设计叫做统一创建原则。
数组也有可变和不可变的,但是数组的可变和不可变是不同的类,也就是类名也不同。
在Scala中如果使用保留字或关键字的话要使用``,如:`class`
Scala默认导入:import java.lang._ 、 import scala._ 、 import Predef._
数组
List
Set
Map
元组
队列
堆栈
其他
Case匹配
样例类
密封类
偏函数
高阶函数
闭包
柯里化
类
构造器
主构造器
辅构造器
嵌套类/内部类
伴生对象
提取器
应用程序对象
枚举
包对象
特质、继承
类型转换&类型检查
隐式转换
泛型
视图界定
上下文界定
上界
其他的自己去试……
pom.xml
Actor
Actor是Scala2.10.x版本(测试时注意pom文件引入的版本),及以前版本的Actor。
Scala在2.11.x版本后将Akka加入其中,并且作为默认的Actor,老版本的Actor已经废弃了。
Scala的Actor能够实现并行编程的强大功能,他是基于事件模型的并发机制,Scala是运用消息(message)的发送接收实现多线程,使用Scala能够更加容易的实现多线程开发。
对比
Java内置线程模型 |
Actor |
共享数据 – 锁 |
Share Nothing(不共享任何数据) |
每个Object有一个monitor,监视多线程对共享数据的访问 |
不共享数据,Actor直接通过message通信 |
加锁的代码段,用Synchronized标识 |
|
死锁的问题 |
|
每个线程内部都是顺序执行 |
每个Actor内部都是顺序执行 |
对于Java,我们都知道他的多线实现需要对共享资源(变量、对象等),使用Synchronized关键字进行代码块同步、对象锁互斥等,而且经常一大堆的try…catch语句加上wait方法、notify方法,notifyAll方法(新版本有单独的锁对象等等),感觉有点痛苦。
原因在于Java多数使用可变状态的对象资源,对这些资源进行共享来实现多线程编程的话,资源的竞争和防止对象状态被意外修改是非常重要的,而且对象状态的不变性也难以保证。
在Scala中,通过复制不可变状态的资源(也就是对象,连函数、方法也是)的一个副本,在基于Actor的消息发送接收机制进行并发编程。
Actor执行顺序
1.调用start()方法启动Actor
2.调用start()方法后,act()方法会被执行,还有一些初始化方法
3.向Actor发送消息
Actor并发是发送消息的方式
发送消息的方式
! |
发送异步消息,没有返回值 |
!? |
发送同步消息,等待返回值 |
!! |
发送异步消息,返回Future[Any] |
剩余内容请阅读:https://blog.csdn.net/Su_Levi_Wei/article/details/85391031