- 函数是Scala的核心
函数定义:
def 函数名([参数列表]):[返回值]={
函数体
return [表达式]
}
def square(x: Int): Int = {
println(x)
x * x //return
}
def sayHello(x:String):Unit={
println("Hello ! "+x)
}
- 参数传递
1.传值调用(call-by-value)
def square(x: Int): Int = {
println(x) //3
x * x //计算3*3
}
square(1+2) //先计算1+2
传值调用时,参数只在调用时计算一次,后续重复使用计算的结果
2.传名调用(call-by-name)
def square(x: => Int): Int = {
println(x) //计算1+2
x * x //计算(1+2)*(1+2)
}
square(1+2) //调用时不计算
传名调用时,参数在调用时不会计算,只有真正用到参数时才计算
- 命名参数
通常情况下,传入参数与函数定义的参数列表一一对应
命名参数允许使用任意顺序传入参数
def printName(first:String, last:String) = {
println(first + " " + last)
}
//Prints "John Smith"
printName("John","Smith")
printName(first = "John",last = "Smith")
printName(last = "Smith",first = "John")
- 参数缺省值
Scala函数允许指定参数的缺省值,从而允许在调用函数时不指明该参数
def printName(first:String="John", last:String="Smith") = {
println(first + " " + last)
}
//Prints "John Smith"
printName()
- 匿名函数
指不含函数名称的函数
匿名函数定义
“=>”左边为参数列表
“=>”右边为函数体
(参数列表)=>{函数体}
如果函数体包括多条语句,应使用“{}”包含
(x:Int)=>x*x
(x:Int)=>{println(x);x*x}
() => { System.getProperty("user.dir") }
val f1=(x:Int)=>{println(x);x*x}
f1(2)
- 高阶函数
高阶函数可以将其他函数作为参数或者使用函数作为输出结果
//函数作为参数
def doSquare(f:Int=>Int,p:Int)=f(p)
def square(x:Int):Int=x*x
doSquare(square,square(2))
//函数作为返回值
//返回类型为函数(Int=>Int)
def doSquare()={
(x:Int)=>x*x
}
doSquare()(2)
- 中置表达式
中置(缀)表达式是对只有一个参数的方法调用约定
当方法只有一个参数时,可以省略“.”和“()”
//示例1
1 to 10
//实际调用
1.to(10)
//示例2
List(1,2,3).map(x=>x+1).foreach(println)
//使用中置表达式
val f=(x:Int)=>x+1
List(1,2,3) map f foreach println
- 函数嵌套
Scala函数内可以定义函数,函数内的函数也称局部函数或者内嵌函数
//使用函数嵌套实现阶乘运算
def factorial(i: Int): Int = {
def fact(i: Int, accumulator: Int): Int = {
if (i <= 1)
accumulator
else
fact(i - 1, i * accumulator)
}
fact(i, 1) //不能在factorial()之外调用
}
- 柯里化(Currying)
方法可以定义多个参数列表,当使用较少的参数列表调用多参数列表的方法时,会产生一个新的函数,该函数接收剩余的参数列表作为其参数。这被称为柯里化
//单参数列表
def modN(n: Int,x: Int) = ((x % n) == 0)
//多参数列表
def modN(n: Int)(x: Int) = ((x % n) == 0)
//新函数接收剩余的参数列表作为其参数
def f1(x: Int) = modN(10)(x)
def f2(n: Int) = modN(n)(10)
def f3 = modN(10)(_)
- 隐式参数
方法可以具有隐式参数列表,由参数列表开头的implicit 关键字标记
implict只能修改最尾部的参数列表,应用于其全部参数
Scala可自动传递正确类型的隐式值
通常与柯里化函数结合使用
def sum(x:Int)(implicit y:Int)=x+y
implicit var a=10 //将作为Int类型隐式值自动传递
sum(10) //20
- 隐式函数
隐式函数也称隐式转换,使用implicit修饰的函数
应用场景
类型转换
implicit def double2Int(x:Double)=x.toInt
val i:Int=3.5
类型增强
implicit def bool2Int(x:Boolean)=if(x) 1 else 0
println(1+true)
- 闭包
闭包是依照包含自由变量的函数字面量在运行时创建的函数值
闭包是对函数本身及其所使用的自由变量的统一定义
val y=1
val add=(x:Int)=>x+y //add是闭包,y是自由变量
闭包的变量绑定
闭包可捕获自由变量的变化
闭包对捕获变量作出的改变在闭包之外也可见