Scala 基础
Scala 特点
Scala全称为 Scalable Language,即“可伸缩的语言”, 它是一种现代多范式编程语言,旨在以简洁、优雅和类型安全的方式表达常见的编程模式,它无缝集成了面向对象语言和函数式语言的功能。
Scala 是一种面向对象的语言,每个值都是一个对象,每个方法都是调用。
Scala 也是一种函数式编程语言,每个函数都是一个值。
Scala可以与Java实现无缝对接,Scala可以直接调用Java中的字段,继承Java类,实现Java接口,Scala复用并包装了原生的Java类型,并支持隐式转换。
Scala 提供了一种轻量级语法来定义匿名函数,它支持高阶函数,它允许嵌套函数,Scala 的案例类及其对模式匹配的内置支持提供了代数类型的功能,这些类型在许多函数式语言中使用。
Scala基本命名规范
1、通常一行一条命令,末尾无需添加分号。
2、若一行包含多条命令,两两之间用分号隔开,建议非特殊语法不允许主动这样写代码。
3、过程中导包,过程中定义函数
变量与常量的命名规范
创建变量:必须赋初值
1、可以不指定变量的具体类型如 var a = 5
,则变量的类型由【首次】赋值的值类型决定且锁定。
2、若声明时已指定变量类型如 var a:String = ""
,则类型不可更改。
var variableName[:Type] = V
创建常量且初始化后,常量的类型和值都将锁定
val VAL_NAME[:Type] = V
标识符的命名规范
Scala对各种变量、方法、函数等命名时使用的字符序列称为标识符,即:凡是自己可以起名字的地方都叫标识符。
命名规则
Scala中的标识符声明,基本和Java是一致的,但是细节上会有所变化,有以下三种规则:
(1)以字母或者下划线开头,后接字母、数字、下划线
(2)以操作符开头,且只包含操作符(+ - * / # !等)
(3)用反引号…包括的任意字符串,即使是Scala关键字(39个)也可以
数据类型
// 类型层次结构(类似菱形结构)
Any
AnyVal AnyRef
Unit(≈Void),Boolean,Byte,Short,Char,Int,Long Float,Double, BigInt,BigDecimal,String,List
Null
Nothing
上述数据类型中 Byte、Short、Int、Long 和 Char 类型统称为整数类型,整数类型加上 Float 和 Double 统称为数值类型,Scala 数值类型的取值范围和 Java 对应类型的取值范围相同
Any 是所有类型的超类型,也称为顶级类型。它定义了某些通用方法,有 AnyVal 和 AnyRef 两个直接子类,不管是引用类型还是值类型都是对象
Scala数据类型仍然遵守低精度的数据类型向高精度数据类型自动转换(隐式转换)
AnyVal表示值类型,有九种预定义的值类型,它们是不可为空的
Unit 表示无值,等同于 Java 中的 void,用作不返回任何结果的方法的结果类型。Unit 只有一个实例值,写成 ()
AnyRef表示引用类型,所有非值类型都定义为引用类型,Scala 中的每个用户定义类型都是 AnyRef 的子类型
Null 是所有引用类型(即 AnyRef 的任何子类型)的子类型,它有一个由关键字 literal 标识的值。 主要是为了与其他 JVM 语言的互操作性而提供的,几乎不应该在 Scala 代码中使用。
Nothing是所有类型的子类型,也称为底部类型,它一个常见的用途是发出非终止信号,例如抛出的异常、程序退出或无限循环。
运算符
算术运算符:(+,-,*,/,%)
关系运算符(==,!=,>,<,>=,<=)
逻辑运算符 (&&,||,!,&,|)
位运算符(~,&,|,^,<<,>>,>>>)
赋值运算符 (=,+=,-=,*=,/=,%=,<<=,>>=,&=,^=,|=)
Scala 运算符的使用几乎和Java类似,下吗,下面介绍几种差异:
运算符即方法
Scala的面对对象比Java更加纯粹,在Scala中一切都是对象,例如对于1+1
来说,实际上是调用了Int
类中名为+
的方法,因此1+1
也可以写为1.+(2)
Int
类中包含了多个重载的+
方法,用于分别接收不同类型的参数
逻辑运算符中的 & 和 |
和Java语言一样,在 Scala 中 &&,|| 的执行是短路的,即如果左边的表达式能确定整个结果,右边的表达式就不会被执行,这满足大多数使用场景。
但是如果需要在无论什么情况下,都执行右边的表达式,则可以使用 & 或 | 代替。
算术运算符中没有的 ++ 和 –
在 Scala 中没有 Java 中的++
和--
运算符,想要实现类似的操作,只能使用+=1
,或者-=1
程序逻辑
惰性表达式
一切都是表达式 val expr = {} 声明时执行
惰性表达式 lazy val expr = {} 使用时执行
lazy 关键字用于延迟对象或值的初始化
使用 lazy 修饰一个变量时,Scala 会在第一次访问该变量时才执行其初始化代码,而不是在对象创建时就执行
这种延迟初始化可以用于提高性能,或者在需要根据某些条件动态初始化值时非常有用
lazy 修饰的变量是不可变的(val),因为它们只能被初始化一次
lazy 修饰的变量在第一次访问时才会初始化,之后的访问将直接返回缓存的值
如果类中有 lazy 修饰的变量,确保在类的其他部分不会提前触发这些变量的初始化
条件表达式 if
Scala中if/else
语法结构和Java中的一样,唯一不同的是,Scala中的if
表达式是有返回值的
val age = 18
if(age>=18){
// 边界模糊使用{}
println(s"${age}是成年")
}else{
println(s"${age}是未成年")
}
类三元运算符(本质:一切都是表达式)
val rst = if(CONDITION) V1 else V2
val age = 18
val str = {if(age>=18) "成年" else "未成年"}
println(str)
循环 while do…while
var n = 0
while (n < 6) {
n += 1
println(n)
}
// 循环至少要执行一次
do {
n += 1
println(n)
} while (n > 6)
for循环
for(item <- COLLECT){
...
}
for(index <- start(inclusive) TO end(inclusive)){
...index...
...
}
for(index <- start(inclusive) UNTIL end(exclusive)){
...index...
}
val range = 1 to 10 by 2
val range2 = 1 until 10 by 3
val range3 = Range(1,10,3)
for(e <- range){
println(e)
}
for(e <- 1 until 20; if e%3==0){
println(e)
}
没有break和continue
Scala 中并不支持 Java 中的 break 和 continue 关键字
元组
元组 TupleN[T1,...,TN](相当于提供了自定义的22个类)
T :泛型
N :1~22
():表示元组
注意:为避免冲突,须知()还可以表示:
1、数组下标提取 array(int)
2、方法的参数列表 method(p1,...,p2)
元组类型表达:推荐 syntactic suger 语法糖
(String, Int) <=> Tuple2[String,Int]
二元组的声明和初始化
val tp2 = ("java", 88) // 实际应用:最简语法
val tp2: (String, Int) = ("java", 88) // 初学推荐,语法糖
val tp2: Tuple2[String,Int] = Tuple2("java", 88)
println(s"${tp21._1} ${tp21._2}") // java 88
元组的使用
val v1 = tp2._1
val v2 = tp2._2
val it:Iterator[Any] = tp2.productIterator
补充:Option[T]
使用:
val opt:Option[T] = ...
val rst = opt.getOrElse(default:T)
例子:
val opt : Option[Int] = array.find(_ >= 100)
val rst: Int = opt.getOrElse(-1)
println(rst)
设计:(多态)
None extends Option
Some extends Option
def add(a:Int,b:Int):Option[Int] = {
val sum = a + b
if(sum>100){
None
}else{
Some(sum)
}
}
val opt: Option[Int] = add(35, 85)
val rst: Int = opt.getOrElse(-1)
println(rst) // 输出 -1
val opt: Option[Int] = add(35, 45)
val rst: Int = opt.getOrElse(-1)
println(rst) // 输出 80
// 类型别名:简化复杂的类型名称
type Alias = Type
type S = String
var str:S = "henry"