Scala 第一篇 基础篇
Scala 第一篇 基础篇
一、变量与常量
1、变量
创建变量:必须赋初值
1、可以不指定变量的具体类型如 var a = 5,则变量的类型由【首次】赋值的值类型决定且锁定。
2、若声明时已指定变量类型如 var a:String = “”,则类型不可更改
1 |
|
2、常量
创建常量且初始化后,常量的类型和值都将锁定
1 |
|
二、数据类型
1、数据基本类型概览
Any: 所有类型的超类(顶级类型)
AnyVal: 值类型的超类
AnyRef: 引用类型的超类
Unit: 无值,类似java中的void
Nothing: 所有类型的子类
Null: 表示null或空引用
2、元组的声明与使用
元组 TupleN[T1,…,TN] (复合类型)
T :泛型
N :1~22
():表示元组
元组类型表达:推荐 syntactic suger 语法糖
(String, Int) <=> Tuple2[String, Int]
二元组的声明和初始化
1 |
|
1 |
|
注意:为避免冲突,须知()还可以表示:
- 数组下标提取 array(int)
- 方法的参数列表 method(p1,…,p2)
3、Range介绍和使用
Range 属于值类型的超类 AnyVal,表示一个连续的数字序列。
通过to
方法或until
方法创建
1 |
|
4、Option 类型的使用和设计
Option 是 Scala 中用来表示可能包含值或者不包含值的容器类型。通常用于避免空指针异常,因为它要求显式地处理可能为空的情况。
1 |
|
函数的设计利用 Scala 中的
Option
类型,以一种更安全和更函数式的方式处理可能为空的情况。通过返回Option
类型,明确地表达了可能存在结果和不存在结果的两种可能性,从而避免空指针异常等问题。
1 |
|
5、类型别名
简化复杂的类型名称
1 |
|
三、运算符
跟Java,C++等没什么区别
1 |
|
四、程序逻辑
1、一切都是表达式
1 |
|
1 |
|
惰性表达式举例
1 |
|
2、分支语句
if...else
语句
1 |
|
模式匹配(重点)
在 Scala 中,模式匹配中的条件守卫允许在模式匹配的基础上增加额外的条件判断。当模式匹配成功后,会检查守卫条件是否为真,只有条件为真时,才会执行相应的逻辑
数值
1
2
3
4
5
6
7
8val dial = Random.nextInt(4)
val rst = dial match {
case 0 => "余额"
case 1 => "充值"
case 2 => "活动"
case 3 => "贷款"
case _ => "未知"
}字符串与条件守卫
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17val content = "123456@qq.com"
val rst = content match {
case a if a.matches("\\w+@\\w{2,}\\.(com|cn)") => "email"
case a if a.matches("1[3-9]\\d{9}") => "handset"
case "NULL" => "nothing"
case _ => "unknown"
}
println(rst) //输出:email
val day = "Monday"
day match {
case "Monday" => println("星期一") //最后只调用此行输出:星期一
case "Tuesday" => println("星期二")
case "Wednesday" => println("星期三")
case _ if day.startsWith("T") => println("星期二到星期五")
case _ => println("其他")
}元组
1
2
3
4
5val rst = (7,101) match {
case (3,_) => (3,1)
case (5,a) => if(a%2==0) (5,0) else (5,1)
case _ => (0,0)
}列表
1
2
3
4val rst = List(1,"hive",88) match {
case List(id,"java",score:Int) => if(score>=60) ("java","pass") else ("java","fail")
case _ => ("SKIP","NONE")
}类型
1
2
3
4
5
6val rst = value match {
case a:Int => ("int",a)
case a:(Int,Int) => ("Tuple2",a)
case a:String => ("String",a)
case _ => ("Unknown",1)
}嵌套
1
2
3
4val rst = (1,("java",67)) match {
case (1,(sub:String,score:Int)) => (sub,score)
case _ => ("UnknownFormat",1)
}
3、循环语句
while
循环
1 |
|
do while
循环
1 |
|
for
循环
有多种不同的用法和语法糖
1 |
|
五、集合
scala 支持运算符的重载
immutable 不可变集合包,mutable 可变集合包
默认导入不可变集合包
使用可变集合需要先import scala.collection.mutable,再通过 mutable.T 使用
常用集合:List、Set、Map、Array
1 |
|
1、List
1 |
|
List分组体验代码
1 |
|
输出结果
1 |
|
2、Set
1 |
|
Set 体验差&~、交&、并| 代码
1 |
|
输出结果
1 |
|
3、Map
1 |
|
Map体验 += -= ++ 代码
1 |
|
输出结果
1 |
|
4、Array
1 |
|
Array体验 += -= ++ 代码
1 |
|
输出结果
1 |
|
备注:Array 和 List 是两种不同的集合类型,区别如下
- 可变性:
- Array 是可变的,可以修改其元素的值,并且可以改变数组的长度。
- List 是不可变的,一旦创建后,就不能修改其元素或长度。如果需要添加、删除或修改元素,可以通过创建新的 List 实例来实现。
- 实现方式:
- Array 在底层是通过 Java 数组来实现的,它提供了快速的随机访问(通过索引)和可变性。
- List 则是使用链表(Linked List)来实现的,每个元素都连接到下一个元素,因此访问和修改操作的效率较低,但对于添加和删除元素来说更加高效。
- 类型:
- Array 是一个包含固定大小元素的集合,元素类型可以是任意类型,甚至可以是不同类型。
- List 是一个包含有序元素的集合,元素的类型相同,并且列表的长度可以动态增长或缩减。
六、函数
1、普通函数, 匿名函数
普通函数:最常见的函数类型
匿名函数:也称为函数字面量或 Lambda 表达式,没有名称,直接定义在代码中
函数定义
1 |
|
字符串插值函数
字符串插值函数属于 Scala 中的内置函数
字符串插值函数允许将变量、表达式或者其他字符串插入到字符串字面量中,形成一个新的字符串。
Scala 提供了三种常用的字符串插值函数
1 |
|
s 插值器:用于字符串插值,允许在字符串中引用变量或表达式。
1 |
|
f 插值器:用于格式化字符串,类似于 C 语言中的 printf 函数。
1 |
|
raw 插值器:用于原始字符串,不会对字符串中的特殊字符进行转义。
1 |
|
2、高阶函数(重点)
接受函数作为参数或返回函数的函数。
1 |
|
柯里化函数
将多个参数列表转换为一系列函数调用,每次调用返回一个新的函数
1 |
|
分析以下两个方法的区别
1 |
|
func1
和 func2
实现的功能是相同的,只是在参数列表的形式上有所不同。使用柯里化的形式可以使代码更加灵活,提高了函数的复用性和可读性。
函数作为参数传递的三种方式
1 |
|
3、隐式参数,隐式函数
隐式函数作用:共用,简化
不建议使用太多,了解即可
场景一
1 |
|
场景二
1 |
|
1 |
|
4、偏函数
只对输入的某些值定义的函数,而对其他值不进行定义。
1 |
|
5、总结
一、命名参数:
1、理解:默认入参规则是按方法或函数的参数列表顺序传参
2、应用:按 “参数名=值” 格式可以不遵循原始参数列表顺序传参
二、参数缺省值(默认值)
1、语法:声明方法时可以通过类似 (a:Int=5,…) 形式给参数提供【默认值】
2、应用:带有默认值的参数,若需要传入的就是默认值,则可缺省
三、匿名函数:将函数作为方法参数传递
1、语法:(参数列表)=>{方法体}
四、高阶函数
1、现象:将函数作为方法参数或返回类型
2、应用:函数作为返回类型:柯里化
五、中置表达式
1、语法:var v = 左元素 函数 右元素
2、案例:var range = 1 to|until 10
3、注意:方法的参数【只有一个参数】才可以使用中置表达式
六、嵌套函数
1、语法:允许在一个函数内部声明一个函数,作用域限当前函数内部
七、隐式参数
1、语法:参数前添加 implicit 关键字
2、限制:只能是最后一个参数列表且独占一个参数列表,自动传入同类型隐式值,通常和柯里化配合使用
八、隐式函数
1、语法:声明函数时,在 def 前添加 implicit 关键字
2、使用:类型转换,类型增强
1
2
3
4
5
>implicit def toInt(str:String)=str.toInt
>val b:Int = "123" // 隐式转换
>implicit def bool(bool:Boolean) = if(bool) 1 else 0
>val a:Int = false
九、闭包
1、概念:在函数内使用函数外定义的自由变量,则该函数即闭包
2、例如:
1
2
>var a = 5
>val add = (b:Int) => a+b3、闭包能够捕获自由变量的变化,闭包对自由变量做出的改变闭包外亦可见(惰性处理:即函数执行后产生作用)
6、补充:下划线 _
用途。
可以用于表示各种不同的语法元素,具体取决于上下文
通配符:在模式匹配、参数列表、导入语句等中,下划线 _
可以用作通配符,表示匹配任意值或任意参数。
1 |
|
占位符:在部分应用函数、匿名函数等场景中,下划线 _
可以作为占位符,表示一个参数的位置,类似于匿名函数中的参数。
1 |
|
部分应用函数:在柯里化函数中,下划线 _
可以用作占位符,表示对某个参数进行部分应用,生成一个新的函数。
1 |
|
占位符语法糖:在某些情况下,下划线 _
可以用作语法糖,简化代码书写。
1 |
|
七、数组方法(重点)
一、创建数组
1 |
|
备注:
Seq
是一个 trait(特质),用于表示序列(Sequence)。序列是一个有序的集合,可以包含重复的元素。Seq
特质定义了一些常见的序列操作,例如获取元素、迭代、转换等。Seq
特质有许多具体的实现类,其中一些常见的包括List
、Vector
、ArrayBuffer
等。这些实现类提供了不同的性能和特性,以满足不同的使用场景。
二、基本操作
1 |
|
三、查找,定位
1 |
|
四、数据拷贝,移植
1 |
|
五、添加
1 |
|
备注:
++=
,:+
,+:
最终类型由左侧表达式的类型决定
六、删除
1 |
|
七、修改
1 |
|
八、提取
1 |
|