Scala语言基础
1 语言介绍
- 他已经出生15年了,就像明星一样,谁都不可能一开始就人气爆棚粉丝无数,得慢慢混。
- 成功原因:完全兼容java代码。
- 身世介绍
- Scala在2004年正式问世,他的爸爸是Martin Odersky,这位老头同时也是Genenric Java的爸爸。神不神奇!Scala和Genenric Java居然是亲兄弟。
- Scala的全称叫scalable,可伸缩的意思。说白了就是可以简单又可以复杂。scala是个纯正的面向对象语言,并且具备函数式编程特性,这也是他最吸引人的地方。
- Scala之所以这么受欢迎还有一个原因,那就是Spark。专为大规模数据处理而设计的快速通用的计算引擎,这正是spark的最好诠释,关于spark的更多信息请百度。spark就是Scala编写的,所以想了解spark的优越性能及应用就必须得学习Scala。
- 学语言很枯燥,案例走一遍,有个印象,做demo用到回来看看就可以了,不要太在意,熟能生巧。
2 变量和数据类型
2.1 注释
- 单行注释
//这是单行注释
- 多行注释
/*
这是多行注释
*/
- 文档注释
/**
这是文档注释
*/
2.2 变量
2.2.1 变量声明
变量声明:var 变量名:类型 = 初始值
常量声明:var 变量名:类型 = 初始值
Scala中可以不写 ; --->一般情况我们都不写,因为;本来就对代码没有什么意义;
Scala中有自动类型推断,所以一般情况都可以省略,故可以写成如下方式。
变量声明:var 变量名 = 初始值
常量声明:var 变量名 = 初始值
在函数式编程中,能用常量就用常量,因为多线程中变量会引起线程安全问题。
2.2.2 数据类型
- Any:所以类的父类
- AnyVal:值类型->类似Java中的基本类型
- 在Java中基本类型int,对应Scala中的Int,注意不是包装类,在Scala中认为都是对象,故首字母都是大写
- StringOps:在Java中String是引用类型,在Scala中是值类型,这个类对String进行了拓展,也可以直接使用Java的String类
- Unit:对应Java中的Void,但是Void没有返回值,而Unit有返回值:
()
- AnyRef:引用类型
- Null:所有引用类型的子类,值为
null
- Null:所有引用类型的子类,值为
- AnyVal:值类型->类似Java中的基本类型
- Nothing:所有类的子类
- 如果需要使用值类型的初始值,需要使用 _ 如:var name:String = _
2.2.3 类型转换
和Java一样,Scala也分自动类型转换和强制类型转换
自动类型转换规则和Java一样,都是从范围小类型转换到范围大类型
强制类型转换和Java不一样,Scala是调用方法的方式来完成转换
- 强制类型转换和自动类型转换
object Demo {
def main(args: Array[String]): Unit = {
//强制类型转换
val a = 10
println(a.toDouble)//10.0
/**
*自动类型转换
* byte->short->int->long->float->double
* char->int->long->float->double
*/
val b:Double = 10
println(b)//10.0
// 如下这种自动类型转换会失败,因为不能自动类型转换不能大转小
// val c:Int = 10.0
}
}
3 字符串转换
object Demo1 {
def main(args: Array[String]): Unit = {
//name = zhangsan,age = 10 sal = 50.56
printf("name = %s,age = %d sal = %.2f", "zhangsan", 10, 50.55555)
//name = lisi,age = 30
val name = "lisi"
val age = 20
println(s"name = ${name},age = ${age + 10}")
/**
* a
* b
* c
*/
val s =
"""
|a
|b
|c
""".stripMargin
println(s)
}
}
4 If Else
Scala中没有三元运算符,只能使用If Else来实现其功能,写法和Java一样
Scala中没有switch
Scala中,任何语法结构都有类型和值,返回最后一行代码的值。如If Else,赋值语句,代码块等等
Scala中 == 等价于Java中的equals()方法,eq 等价于Java中的 ==
object Demo2 {
def main(args: Array[String]): Unit = {
var i = 1
if (true) {
i = 2
} else {
i = 0
}
//2
println(i)
}
}
object Demo3 {
def main(args: Array[String]): Unit = {
val func = if (true) {
1
2
} else {
0
}
//2
println(func)
}
}
object Demo4 {
def main(args: Array[String]): Unit = {
val func = if (true) {
}
//()
println(func)
}
}
5 循环
while和do while和Java一样
for不像Java,其实是一种遍历
5.1 while
object Demo5 {
def main(args: Array[String]): Unit = {
var i = 1
while (i < 5) {
println(i)
i += 1
}
}
}
5.2 do while
object Demo6 {
def main(args: Array[String]): Unit = {
var i = 1
do {
println(i)
i -= 1
} while (i > 1)
}
}
5.3 for
object Demo7 extends App {
//遍历序列
for (x <- "123456") {
println(x)
}
//间隔,反转:打印10到1,并且间隔2个打印
for (y <- 1.to(10, 2).reverse) {
println(y)
}
//循环守卫:打印1到10的偶数
for (z <- 1.to(10) if z % 2 == 0) {
println(z)
}
//for推到:使循环可以返回最后的值,如下1到10的平方
val a = for (z <- 1.to(10)) yield z * z
println(a)
}
import scala.util.control.Breaks._
object Demo8 extends App {
//退出循环
breakable(
for (x <- 1.to(10)) {
if (x == 5) break()
println(x)
}
)
}
6 Lambda及函数
函数式编程强调执行的结果而非执行过程,倡导利用若干简单的单元让计算结果不断演进,逐层推到复杂运算,而不是设计一个复杂的运算过程。
在Scala中,函数也是一个对象,会有返回值,可以作为值传递给另外的函数。
函数的定义: def 函数名(参数1:参数1类型,参数2:参数2类型):函数返回值 = { 代码块 }
函数返回值是可以自动推到的: def 函数名(参数1:参数1类型,参数2:参数2类型)= { 代码块 }
函数形参都是val常量
-
纯函数
-
不能产生副作用
- 函数不会产生副作用,除了返回值外,不修改程序的外部状态(如修改全局变量,入参等)
- 常见副作用:改变外部变量的值、向磁盘写入数据、将页面的一个按钮设置为能否点击
-
引用透明
- 函数的运行不依赖于外部的变量或状态,简单的理解为多次调用,不会因为外部值而改变返回结果。
- 天然适合并编程,因为调用函数的结果具有一致性,所以根本不需要加锁,也不存在死锁
-
//纯函数
def add(a: Int, b: Int): Unit = {
a + b
}
//纯非函数
def add1(a: Int, b: Int): Unit = {
//破坏了纯函数,产生副作用
println("打印功能")
a + b
}
//纯非函数
var x = 0;
def add2(a: Int, b: Int): Unit = {
//破坏了纯函数,产生副作用
x = 100
a + b
}
var x = 1;
def add(a: Int, b: Int)= {
//破坏了纯函数
a + b + x
}
println(add(1, 2)) //4
x = 10
println(add(1, 2)) //13
- 可变形参函数
参数类型*为可变形参,传入一个序列中的每个元素。
def add(a: Int*) = {
a.sum
}
println(add(1, 2, 3)) //6
def add(a: Int*) = {
a.sum
}
val arr: Range.Inclusive = 1.to(3)
println(add(arr: _*)) //6 序列展开需要使用: _*
- 函数参数默认值
def myconcat(x: String, pre: String = "", suf: String = "") = {
pre + x + suf
}
//abc
println(myconcat("abc", "", ""))
println(myconcat("abc"))
println(myconcat("abc", suf = "