函数式编程是结构化编程的一种,主要思想是把运算过程尽量封装成一些列嵌套的函数调用
函数式编程中,最重要的就是函数 ,函数可以作为数据类型,可以当做其他函数的参数
def 函数名 ([参数名:参数类型],…)[[:返回值类型]=]{
语句…
return 返回值
}
1)声明关键字 def
2)参数可以没有,如果有多个参数逗号分隔
3)函数返回值可以有也可以没有,形式如下
:类型= 标识返回指定类型的结果
= 表示返回不定类型的结果
空 没有返回值,return 不生效
4)如果有返回值但是没有return,默认以执行到的最后一行程序的执行结果作为返回值
1)函数可以没有形参,如果么有调用时可以不带()
2)参数和返回值的类型可以是值和引用类型
3)scala中函数可以根据最后一行代码自动推断出返回值的类型,这种情况下return 关键字可以省略
def sum(n1:Int,n2:Int):Int={n1+n2}
4)因为scala 可以自行腿短所以在省略return的场合,返回值的类型也可以省略
def sum(n1:Int,n2:Int)={n1+n2}
5)如果函数使用了return关键字,函数就不能自动腿短了,这时函数定义中要写明返回类型,如果什么都不写 return返回();
def sum2(n1:Int,n2:Int):Int={return n1+n2} //写了return 返回值类型必须写明否则报错
def sum3(n1:Int,n2:Int){return n1+n2} //输出 res=() 如果没有返回值那么即使有return 返回结果也是 ()
6)如果函数无返回值(unit),那么函数体中及时使用了return关键字,也不会有结果返回
def sum4(n1:Int,n2:Int):Unit={return n1+n2}//输出 res=() 如果没有返回值那么即使有return 返回结果也是 ()
7)如果明确函数无返回值或不确定返回值类型,那么返回值类型可以省略,或生命为Any类型,如下两种方式效果相同
def f1(s:String){ if(s.length>=3) s+“123” else 3}
def f1(s:String):Any={ if(s.length>=3) s+“123” else 3}
8)scala中任何语法结构都可以嵌套其他语法结构,即函数中可以再声明函数,类中可以再声明类,方法中可以再定义方法
def f2(s:String):Any={
def hello(s:String)={"hello,"+s}
return hello(s)
}
9)scala函数的形参在声明时可以直接指定初始值(默认值),调用函数时,如果没有指定实参,则会使用默认值
,如果传入了实参则,实参覆盖默认值。
def f3(name:String=“tom”)={“hello,”+name}
10)如果函数的多个参数都指定了默认值,调用时传递的参数,到底是覆盖哪个默认参数 就不能确定了,这个时候可以采用带名参数
def test(): Unit ={
println(f4())
println(f4("p1n",22))
println(f4(p3="p1n",p2=23))
}
def f4(p1:String="p1",p2:Int=33,p3:String="p3",p4:String="p4")={
p1+"_"+p2+"_"+p3+"_"+p4
}
11)递归函数未执行之前无法判断结果类型,因此必须声明结果类型
def f5(n:Int):Int ={if(n<=0)1 else f5(n-1)} 如果不声明返回类型会报错
12)支持可变参数 args 是一个集合,可以通过for循环访问到里边的值 可变参数必须在参数列表的最后
def f6(args:Int*){} //0-n个参数
def f6(args:Int*):Int ={
var sum = 0;
for(item<-args){
sum+=item;
}
return sum;
}
返回类型为Unit的函数称之为过程,如果明确没有返回值 等号也可以省略
如 : def test(): Unit ={} def test2(){}
如果函数没有声明返回类型,但是有等号,这个时候回自动判定返回类型,实际上有返回类型,不属于过程
当函数的返回值被声明为lazy时,函数的执行将被推迟,知道我们首次获取此值时,这个时候函数才会被实际执行,
这种函数称之为惰性函数,在java中称之为懒加载。懒汉模式
*lazy 不能修饰var类型的变量
*不单是在函数调用时加了lazy函数执行会延迟,声明变量时 如果加了lazy 变量值分配也会被延迟 如 lazy val i =10;
def lazyTest(): Unit ={
lazy val res=sum2(1,2);
println("执行了。。")
println("执行结果:"+res)
}
def sum2(n1:Int,n2:Int):Int={
println("求和逻辑")
return n1+n2
}
输出结果:
执行了。。
求和逻辑
执行结果:3
scala 提供了 try catch 块 来处理异常,try 块包含可能出错的代码,catch 块用来处理发生的异常。
1)工作机制和java 一样,但是Scala没有checked 异常,异常都是在运行时捕获处理。
2)可以使用throw 关键字 抛出一个异常。所有异常都是 Throwable的子类型,throw 表达式 返回类型是Nothing,
因为Nothing是所有类型的子类所以throw表达式可以用在需要类型的地方。
3)catch 块中使用模式匹配思想(case)来做异常的匹配,匹配上后 可以执行多行代码语句
4)catch 中捕获异常时按照顺序来匹配的,因此 越详细的异常应该越靠前,越普遍的异常越靠后,在scala中详细的异常写在后边也不会报错,只不过习惯不好
5)finally 和 java一样,无论有没有异常都会执行,可以用于回收资源
6)方法可以使用 throws 关键字来声明异常,向调用者说明此方法肯能引发的异常,方便调用者进行处理
@throws(classOf[ArithmeticException])
def f10(): Unit ={
}
def testExp(): Unit ={
try{
val r =10/0
}catch{
case ex:ArithmeticException => {
println("捕获了除数为0 的异常")
}
case ex:Exception => {
println("捕获了异常")
}
}finally{
println("执行finally")
}
}