ScalaQuickIN
快速入门 Scala
[TOC]
1. 学习目标
2. Scala 介绍
2.1 Scala 简介
Scala 创始人为 Martin Odersky,马丁·奥德斯基。JDK5 和 JDK8 版本的Java编译器 javac
都是由他和他的团队编写的。
2.2 Scala 的六大特征
一句话总结:Scala 是一门以 JVM 为运行环境的静态类型编程语言,具备面向对象及函数是编程的特性。下面是官网对Scala特性的介绍:
① SEAMLESS JAVA INTEROP 无缝与 JAVA互操作
Java 和 Scala 可以混编,在写 Scala 代码时可以引用 Java 的类。
Scala 运行在 JVM 上,所以 Java 和 Scala 可以自由的混合使用。这也就是在日常编写代码的过程中,经常看到Scala引用了很多Java包的原因。
② TYPE INFERENCE 类型推断(自动推测类型)
使类型系统不是那么的死板(静态)。不要为了类型系统工作,而是让类型系统为你工作。
Scala是一种弱类型语言,即它在编写代码时,不需要像强类型语言(如 Java、C++等)定义变量的类别。
Scala有Int
、Long
、Short
、Byte
、Float
、Double
、Char
、Boolean
这些基础数据类型。但与 Java 不同,在定义变量时,Scala用 var/val
来定义,让其自主判断数据类型。
其中val
是常量,var
是变量,一般来说,用val
比较多(涉及资源的利用)。
1 | // Java 中定义一个变量 |
③ CONCURRENCY & DISTRIBUTION 并发和分布式(Actor)
Scala 在操作集合时使用了数据并行操作。并且使用Actor(Actor是一种不共享数据,依赖于消息传递的并发编程模式, 有效的避免了死锁、资源争夺等情况)来解决并发和分布式中的一些问题。或者使用 futures
类进行异步编程。
使用 Scala 进行并发以及分布式场景下的开发时有得天独厚的优势。
④ TRAITS 特性
将 Java 风格接口的灵活性与类的强大功能相结合。认为是一种多重继承。
其实这就相当于 Java 的接口,但实际上它比接口还功能强大。 与接口不同的是,它还可以定义属性和方法的实现。
简单来说:TRAITS = Interface + Abstract。
⑤ PATTERN MATCHING 模式匹配
更强大的 Switch
,它可以匹配类的层级结构、序列以及更多。
⑥ HIGHER-ORDER FUNCTIONS 高阶函数
函数是一级对象。在保证类型安全的情况下编写它们。在任何地方使用它们,传递给任何东西,即函数可以作为参数传递到函数中。
2.3 具体应用
- Kafka:分布式消息队列,内部代码经常用来处理并发的问题,用 Scala 可以大大简化其代码。
- Spark:方便处理多线程场景,另外Spark主要用作内存计算,经常要用来实现复杂的算法,利用Scala这种函数式编程语言可以大大简化代码。
3. Scala 的安装和使用
3.1 Windows 下安装 Scala
Scala下载地址:The Scala Programming Language (scala-lang.org)
① 进入下载地址后,选择合适的Scala版本进行安装。记住安装的路径,方便配置环境变量。
② 配置环境变量 SCALA_HOME
③ 验证是否安装成功:进入命令行CMD
,输入 scala -version
,显示版本号及表明配置成功。
3.2 IDEA 2022 中配置 Scala 插件
① 进入IDEA,Files→Settings→Plugins
② 进入Marketolace界面,直接搜索Scala
,安装即可。
③ 在编写 Scala 代码时,双击 Shift
,选择 Add Framework
后,添加 Scala 框架,即可编写 Scala 代码。
4. Scala 基础
4.1 数据类型
数据类型 | 描述 |
---|---|
Byte |
8-bit 的有符号数字,范围在 -128 ~ 127 |
Short |
16-bit 的有符号数字,范围在 -32768 ~ 32767 |
Int |
32-bit 的有符号数字,范围在 -2147483648 ~ 2147483647 |
Long |
64-bit 的有符号数字,范围在 -9223372036854775808 ~ 9223372036854775807 |
Float |
32-bit IEEE 754 单精度浮点数 |
Double |
64-bit IEEE 754 双精度浮点数 |
Char |
16-bit Unicode 字符,范围 U+0000 ~ U+FFFF |
String |
字符串 |
Boolean |
布尔类型 |
Unit |
表示空值,与其他语言中的 void 相同 |
Null |
空值或者空引用 |
Nothing |
所有其他类型的子类型,表示没有值 |
Any |
所有类型的超类,任何类型都属于Any |
AnyRef |
所有引用类型的超类 |
AnyVal |
所有值类型的超类 |
Nil |
表示长度为0的List |
比较特殊的 None
,是Option
的两个子类之一,另一个是Some
,用于安全的函数返回值。
Scala 推荐在可能返回空的方法使用 Option[X]
作为返回类型。如果有值就返回 Some[X]
,否则返回 None
。
1 | def get(key: A): option[B] = { |
4.2 变量和常量的声明
变量用
var
定义,可修改常量用
val
定义,不可修改定义变量或常量的时候,也可以写上返回值的类型,一般省略,如
val a: Int = 10
常量不可以再赋值
1 | var name = "zhangsan" |
4.3 键盘标准输入
编程中可以通过键盘输入语句来接收用户输入的数据(也就是 Java 中的 Scanner 对象)。
在 Scala 中只需要导入对应的包,比 Java 还要简单,不需要实例化对象。
1 | import scala.io.StdIn |
如上述代码一样,printf()
的用法和 Java 中一样,为格式化输出。注意使用规范即可。
符号 | 含义 |
---|---|
%d |
十进制数字 |
%s |
字符串 |
%c |
字符 |
%e |
指数浮点数 |
%f |
浮点数 |
4.4 类Class
和 对象Object
- 在编写 Scala 代码时,一般不加分号
;
,如果一行中有多条语句,则可以用分号隔开,如:var a = 10; var b = 20
。 class
默认实现了getter/setter
方法。class
中如果有参数传入,那么这个构造器就是这个类的默认构造器。class
在被new
新建对象的时候,除了方法内部不执行,其他地方的代码都会执行,类似于Java中的工具类。Object
里面不能传递参数,Object
里面的属性和方法都是静态的,类似于 Java 中static
修饰的东西,类似于 Java 中的工具类。- 伴生类和伴生对象,在一个 Scala 文件中,如果
Class
和Object
的名字一样,则互为伴生类和伴生对象。他们可以互相访问到互相的私有成员变量。
1 | class Person(xname:String, xage: Int) { |
4.5 IF-ELSE 语句
Scala 中的条件判断语句同 Java 中的条件判断语句,语法结构基本一致。
1 | import scala.io.StdIn |
4.6 Loop 循环语句
to
和until
语句的区别
1 | object ToUntilDemo { |
for
循环
1 | object ForDemo { |
- Scala 中不能使用类似于
x++
、x--
的操作,需要使用x += 1
或者x -= 1
来完成自增或者自减操作。 for
循环使用yield
关键字返回一个集合,for { 子句 } yield {变量或表达式}
,for
循环中的yield
会把当前的元素记下来,保存在集合中,循环结束后将返回该集合。Scala 中for
循环是有返回值的。如果被循环的是Map
,返回的就是Map
,被循环的是List
,返回的就是List
,以此类推。
1 | object Loop { |
while
和do...while
1 | object Loop { |
5. Scala 函数(方法)
5.1 函数的定义
1 | // 函数(方法) 的定义 |
注意事项:
- Scala 使用
def
关键字告诉编译器这是一个函数(方法) - 我们可以通过在参数列表后面加一个冒号
:
和类型来显式地指定返回类型。 - 函数可以写
返回类型
,也可以不写,会自动推断(最后一行是什么类型,就被推断成什么类型)。有时候不能省略,必须写,比如在递归函数中或者函数的返回值是函数类型的时候。 - Scala 中函数有返回值时,可以写
return
,也可以不写return
,不写return
时会把函数中最后一行当做结果返回。当写return
时,必须要写函数的返回类型
。 - 传递给方法的参数可以在方法中使用,并且 Scala 规定:方法的传过来的参数为常量
val
而不是变量var
。 - 如果去掉函数体前面的等号
=
,那么这个函数返回类型必定是Unit
。这种说法无论函数体里面什么逻辑都成立,Scala 可以把任意类型转换为Unit
。假设,函数里面的逻辑最后返回了一个String
,那么这个返回值会被转换成Unit
,原本逻辑的值会被丢弃。这种方法往往适用于无返回值的函数中。
5.2 递归函数
1 | object FunctionDemo { |
5.3 包含参数默认值的函数
- 和其他语言没有任何区别
- 默认值的函数中,如果传入的参数个数与函数定义相同,则传入的数值会覆盖默认值。
- 如果不想覆盖默认值,且传入的参数个数小于定义的函数的参数,则需要指定参数名称。
1 | object FunctionDemo { |
5.4 可变参数个数的函数
1 | object FunctionDemo { |
5.5 匿名函数
匿名函数有以下几种:
- 有参匿名函数
- 无参匿名函数
- 有返回值的匿名函数
在定义和使用匿名函数时:
- 可以将匿名函数返回给
val
定义的值 - 匿名函数不能显示声明函数的返回类型
在 Scala 中 ,大多数情况下 =>
是匿名函数的显著标志。
1 | object FunctionDemo { |
5.6 嵌套函数
嵌套函数其实就是函数里套了函数。
1 | object FunctionDemo { |
5.7 偏应用函数
偏应用函数是一种表达式,不需要提供函数需要的所有参数,只需要提供部分,或不提供所需参数。
1 | object FunctionDemo { |
5.8 高阶函数
高阶函数:函数的参数
是函数,或者函数的返回类型
是函数,或者函数的参数
和函数的返回类型
是函数的函数。
函数的格式为 (A)=>B
, 后面没有函数体, 此函数接收类型 A
的参数, 返回类型 B
的函数。
- 函数的
参数
是函数:其实就是定义一个传入参数
和返回类型
的模板参数,但是这个模板需要从其他地方实现。
1 | // 函数的参数是函数 |
- 函数的
返回类型
是函数
1 | // 函数的返回类型是函数 |
- 函数的
参数
和函数的返回类型
是函数
1 | def f11(x: Int, f: (Int, Int) => Int): (Int, Int) => Int = { |
5.9 柯里化函数
柯里化函数,或称颗粒化函数,将参数变成颗粒散落简而言之就是将参数不断拆分。柯里化函数基本是在做这么一件事情:只传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数。如果写成公式文字就是这样:
1 | fn(a, b, c, d) => fn(a)(b)(c)(d) |
可以理解为高阶函数的简化,类似于返回类型为函数的函数。
1 | def f12(a: Int, b: Int, c: Int, d: Int) = { |
6. Scala 字符串
Scala
中的字符串和 Java
中的字符串用法几乎完全相同。
String
和 StringBuilder
的区别:String
不可修改,StringBuilder
可修改。
6.1 String
1 | package com.szy.inspur.subowen.rdd.base |
6.2 StringBuilder
1 | package com.szy.inspur.subowen.rdd.base |
6.3 String 的操作方法
万金油append
,append()
不受类型的限制。
7. 集合
7.1 数组
7.1.1 创建数组
1 | /** |