@
函数可以作为值进行传递
- 语法
var f = 函数名 _
- 如果明确了变量的数据类型,那么下划线可以省略
//函数正常的声明与调用
def foo():Int={
println("foo...")
10
}
//将foo函数的执行结果赋值给res变量
//val res: Int = foo()
//println(res)
//函数作为值进行传递 语法:在函数名称的后面 + 空格 加下划线
//注意:将foo函数作为一个整体,赋值给f变量, f是函数类型 ()=>Int
//val f : () => Int = foo _
def f : () => Int = foo _
//这个时候,f就是一个函数,如果要想运行f函数的话,必须得加()
//println(f) //<function0>
//println("-----------------")
//println(f())
//var ff = foo //将函数执行结果赋值给ff
//var ff = foo _ //将函数本身作为值赋给ff
//将函数本身作为值赋给ff 如果明确了变量的类型,那么空格和下划线可以省略
//var ff:()=>Unit = foo
//println(ff)
函数可以作为参数进行传递
- 通过匿名函数
- 扩展函数的功能
- 提高函数的灵活度
//函数可以作为参数,进行传递(大多数情况都是通过匿名函数的形式)
//定义一个函数calculator,该函数接收一个函数类型的参数op,op定义了对两个整数要进行什么样的操作
def calculator(a:Int,b:Int,op:(Int,Int)=>Int): Int ={
op(a,b)
}
//定义一个函数f1,完成两个整数的加法运算
def op(a:Int,b:Int):Int={
a + b
}
//println(calculator(10,20,op))
println(calculator(50, 20, (a: Int, b: Int) => {
a - b
}))
println(calculator(50, 20, _ - _))
println(calculator(50, 20, _ + _))
*/
函数可以作为返回值进行返回
- 函数的嵌套
- 函数链式调用,通过参数传递数据,在执行的过程中,函数始终占据栈内存,容易导致内存溢出
//函数可以作为返回值进行返回----函数的嵌套
def f1():()=>Unit ={
def f2(): Unit ={
println("f2函数被调用了")
}
//将f2作为返回值返回给f1
f2 _
}
//ff就是f2
//var ff = f1()
//ff()
//f1()()
闭包
内层函数访问外层函数的局部变量,会自动延长外层函数局部变量的生命周期,与内层函数形成一个闭合的效果,我们称之为闭包
/*
def f1(): (Int)=>Int ={
var a:Int = 10
def f2(b:Int): Int ={
a + b
}
f2 _
}
*/
//执行f1函数返回f2,将返回的f2赋值给ff变量
//val ff: Int => Int = f1()
//闭包:内存函数f2要访问外层函数f1局部变量a,当外层函数f1执行结束之后,f1会释放栈内存,但是会自动的延长f1函数的局部变量的生命周期,
// 和内层函数f2形成一个闭合的效果,我们将这种闭合的效果称之为闭包
//如果存在闭包,那么编译器会生成包含$anonfun$的字节码文件
//闭包 = 外层函数的局部变量 + 内层函数
//调用ff函数,其实就是调用f2
//println(ff(20))
//也可以直接通过如下方式调用
//println(f1()(30))
println("-----------------------------------")
//以上代码可以转换为如下代码
/*
def f3() ={
var a:Int = 10
(b:Int) => a + b
}
f3()(30)
*/
柯里化
- 将一个参数列表中的多个参数,拆分为多个参数列表
- 好处1:每一个参数列表表示函数清晰明确
- 好处2:简化闭包代码的编写
//柯里化
//将一个函数的一个参数列表中的多个参数,拆分为多个参数列表
//简化闭包代码的编写
def f4()(b:Int):Int = {
var a:Int = 10
a + b
}
println(f4()(20))
//f4在执行的时候,其实会转换为以下结构
/*
def f4() ={
var a:Int = 10
(b:Int) => a + b
}
什么是匿名函数
- 参数的类型可以省略,会根据形参进行自动的推导
- 类型省略之后,发现只有一个参数,则圆括号可以省略;其他情况:没有参数和参数超过1的永远不能省略圆括号。
- 匿名函数如果只有一行,则大括号也可以省略
- 如果参数只出现一次,则参数省略且后面参数可以用_代替