一、scala的特点:
1.Scalable编程语言 (可伸缩的,既可以是脚本语言,又可以为大型服务器所使用)
2.纯正的面向对象的语言
3.函数式语言
4.无缝的Java互操作
二、scala函数式的编程思想:
1.纯函数,不具有副作用
2.引用透明
3.函数是一等公民:一切都是计算,函数式编程中只有表达式和变量!函数也是表达式
三、变量
1.val:定义常量(immutable variable),同java的final,给值后就不能再改变
2.var:定义变量(mutable variable),可以改变赋值的内容
3.lazy val:定义的时候不求值,在第一次使用的时候才会求值,即第一次操作时才会延迟加载
建议使用val
scala> lazy val a=1
a: Int = <lazy>
scala> a
res0: Int = 1
四、数据类型
1.数值类型:Byte、Short、Int、Long、Float、Double
2.布尔类型:true、false
3.字符类型:Char
4.Unit类型:函数无返回值时,定义为Unit类型
5.Nothing和None
6.String:构建于Java的String之上,新增了字符串插值的特性
scala> val string="Nina"
string: String = Nina
scala> s"my name is ${string}"
res1: String = my name is Nina
五、函数
函数/方法的定义:
//主函数
def main(args: Array[String]): Unit = {
println(add(3,4))
println(three())
println(three) //函数没有形参的话,可以直接调用函数名,不需要加小括号
hello()
}
def add(x:Int,y:Int):Int={
x+y
}
def three()=1+2 //方法体只有一行,不需要加大括号
def hello(): Unit ={ //Unit表示函数没有返回值
println("hello world")
}
六、参数
1.默认参数:在函数定义时,允许指定参数的默认值
def main(args: Array[String]): Unit = {
sayName() //不指定参数调用
sayName("Jack")) //指定参数调用
}
def sayName(name:String="Nina"): Unit ={ //默认参数是Nina
println("hello, "+name)
}
结果:
hello, Nina
hello, Jack
2.命名参数:可以更改某一函数中参数的位置,但需要指明该函数的名称,不太建议
3.可变参数:参数的个数可以改变
def main(args: Array[String]): Unit = {
println(sum(1,2)) //可变参数,函数中参数的个数不同,都可以调用sun()函数进行计算
println(sum(1,2,3,4))
}
def sum(numbers:Int*)={ //Int后的*用来匹配可变的参数值
var result:Int=0
for(number:Int<-numbers){
result+=number
}
result
}
结果:
3
10
七、if表达式、for表达式、try表达式、match表达式
1.if表达式
scala> val x=1
x: Int = 1
scala> if (x>0) true else false
res2: Boolean = true
2.for表达式
val arr=Array("Nina","Jack","Linda") //定义了一个Array
arr.foreach(name=>println(name)) //循环打印出arr中内容的一种方法
for(name<- arr) //循环打印出arr中内容的另一种方法
println(name)
3.try表达式:try()、catch()、finally()
try{
Integer.parseInt("dog")
}catch{
case _ =>0
}finally{
println("always be printed")
}
结果:
always be printed
res3: Int = 0
4.match表达式:同Java中的switch
scala> x match{
case 1 =>"one"
case 2=>"two"
case 3=>"three"
case _=>"default"
}
结果:
res4: String = two
八、求值策略
1.call by value:def foo(x:Int)=x
2.call by name:def foo(x:=>Int)=x
call by value 会对函数的形参先求值
//call by value
def foo(x:Int,y:Int)=x*x
结果:foo(3+4,8)->foo(7,8)->7*7->49
//call by name
def foo(x:=>Int,y:=>Int)=x*x
结果:foo(3+4,8)->(3+4)*(3+4)->7*(3+4)->7*7->49
九、柯里化
把具有多个参数的函数转换成一条函数链,每个节点上是单一参数
//普通
def add(x:Int,y:Int)=x+y
//柯里化语法
def add(x:Int)(y:Int)=x+y
十、递归函数
在函数式编程中没有循环,需要通过递归来实现循环
递归会使用到栈,容易溢出,因此改进推出了尾递归函数
尾递归函数:
尾递归函数中所有递归形式的调用都出现在函数的末尾
当编译器检测到一个函数的调用是尾递归时,它就覆盖当前的活动记录,而不是在栈中创建一个新的,从而避免了栈溢出的问题
scala> @annotation.tailrec //声明是尾递归
def fac(n:Int,m:Int):Int={ //m用于记录结果,不停的被覆盖
if(n==1) m
else fac(n-1,m*n)
}
结果:
scala> fac(5,1)
res4: Int = 120