函数特征
1、函数返回值类型推导
函数的返回值类型可以省略,然后 scala 会根据最后一行代码,推导处函数返回值类型
注:
有些情况不能推导:
1. 函数内有 return 语句
2.返回值类型和推导类型不一致
3.递归调用的时候不要推
2、Unit( = 省略)
2.1、如果函数名和函数体之间的 = 省略,那么这个函数用于返回 Unit (隐式的返回Unit),函数就成了一个过程
2.2、如果函数显示指明返回 Unit ,则用于返回 Unit
3、参数为 0 () 可省
3.1、调用函数时,如果函数的参数的个数是 0 ,则圆括号 ( ) 可省略
3.2、在声明函数时,如果不需要参数,则圆括号 ( ) 也可以省略,调用时不能再有圆括号 ( )
object Type1 {
def main(args: Array[String]): Unit = {
println(high) //输出: hello world!
}
def high : String = "hello world!"
4、参数默认为 val
函数的参数默认都是 val, 所以在函数内部不能更改参数的值!!!,如果想修改参数的值,则应该先定义一个新的局部变量,然后去修改局部变量的值!
5、函数参数默认值
声明函数的时候,参数可以带默认值
object Type1 {
def main(args: Array[String]): Unit = {
println(add2(10,20,1)) //输出:31
println(add2(10,20,2)) //输出:32
println(add2(10,20)) //输出:33
}
def add2(a:Int,b:Int,c:Int = 3) = a+b+c
在 java 和 scala 中,默认传递函数参数,是按照位置来的,在 scala 中可使用命名参数来传递
object Type1 {
def main(args: Array[String]): Unit = {
println(add2(10,20,1)) //输出:31
println(add2(10,20,2)) //输出:32
println(add2(10,20)) // 10 传给a,20传给c 不行,会报错,默认传递是按照位置来的
// 解决方案 1 命名参数
println(add(10,c=20)) //输出:33
println(add(c=20,a=50,b=10)) //输出:80
//也可以把函数的默认值放在最后,像 java 一样
}
def add2(a:Int,b:Int = 3,c:Int ) = a+b+c
6、函数可定义在任意位置
object High {
def main(args: Array[String]): Unit = {
foo() // 输出:aaaaaa
}
// 函数内部定义函数
def foo(): Unit ={
def f(): Unit ={
println("aaaaaa")
}
f()
}
}
7、函数当返回值
可以把函数当成一个值返回给函数的调用者,函数的的调用者就可以在函数的外部去调用这个返回的函数
object High {
def main(args: Array[String]): Unit = {
val f1:() => Unit = foo() // 接收函数foo()的返回值
f1() //输出:aaaaaa
}
def foo()={
def f(): Unit ={
println("aaaaaa")
}
f _ //f 空格加下划线,将函数f() 当成一个返回值进行返回
}
}
8、函数当作值传递
object High {
def main(args: Array[String]): Unit = {
foo(f())
foo(f)
foo(f _)
}
def f(): Unit ={
println("aaaa")
}
def foo(x:Any): Unit ={
println(x)
}
}
输出:
1.aaaa
() //其传递的为 Unit 类型
2.aaaa
() //其传递的为 Unit 类型
3.< function0 >
// 加下划线是将函数整体当作参数
foo() 就是一个 高阶函数
如果一个函数 可以返回一个函数作为返回值,或者可以接受一个或多个函数作为参数,那么这个函数就称为高阶函数
object High {
def main(args: Array[String]): Unit = {
foo(f _)
}
def foo(x:() => Unit): Unit ={
println(x)
x()
}
def f(): Unit ={
println("aaaa")
}
}
输出:
< function0 >
aaaa
9、函数与方法
方法:
严格上来说,使用def定义的叫方法,其实不能叫函数
1、函数可以作为值传递,方法不行
object High {
def main(args: Array[String]): Unit = {
//val f = foo 报错,方法不能作为值传递
val f = foo _ // 会进行类型推导
//下划线将方法转为函数
f(10) // 函数 输出:10
foo(10) // 方法 输出:10
}
def foo(a:Int): Unit = println(a)
}
2、函数可以直接定义: ( ) => { }
注:
函数不能声明返回值类型,只能靠推导
val f = (a:Int) => {a*a} //会进行类型推导
val r : Int = f(10)
// 箭头前为参数类型,后为返回值类型
// = 赋值
3、方法转为函数
object High {
def main(args: Array[String]): Unit = {
// 没有环境,必须手动转
val f = add _ // 会进行类型推导 一定要加 _
//有环境,scala 自动转换
val f1 : (Int,Int) => Int = add //可以不加下划线
// 自我定义了类型,不需要推导
}
def add(a:Int,b:Int) = a+b
}
9、匿名函数
没有名字的函数就是匿名函数
用处:
1.作为实参,直接传递给高阶函数
2.直接作为高阶函数的返回值
object High {
def main(args: Array[String]): Unit = {
f(() => {
println("匿名函数")
})
}
def f (op:() => Unit) = op()
}
object High {
def main(args: Array[String]): Unit = {
foo((a:Int,b:Int) => a+b)
foo((a,b) => a+b)
foo(_ + _) //第一个下划线代表第一个参数
foo(_ * _)
//在传递过程中参数类型一般可以利用上下文让 scala 自动推导
}
def foo(add:(Int,Int) => Int) = {
println(add(10, 20))
println(add(1, 2))
println(add(5, 6))
}
}
foo(_ + _) :
1、匿名只能有两个参数
2、每个参数只使用一次
3、第一个下划线代表第一个参数,第二个下划线代表第二个参数