函数
scala支持函数式编程,将来编写Spark/Flink程序中,会大量使用到函数
定义函数
语法
val 函数变量名 = (参数名:参数类型, 参数名:参数类型....) => 函数体
[!TIP]
- 函数是一个对象(变量)
- 类似于方法,函数也有输入参数和返回值
- 函数定义不需要使用
def
定义- 无需指定返回值类型
示例
- 定义一个两个数值相加的函数
- 调用该函数
参考代码
scala> val add = (x:Int, y:Int) => x + y
add: (Int, Int) => Int = <function2>
scala> add(1,2)
res3: Int = 3
方法
一个类可以有自己的方法,scala中的方法和Java方法类似。但scala与Java定义方法的语法是不一样的。
定义方法
语法
def methodName (参数名:参数类型, 参数名:参数类型) : [return type] = {
// 方法体:一系列的代码
}
[!NOTE]
- 参数列表的参数类型不能省略
- 返回值类型可以省略,由scala编译器自动推断
- 返回值可以不写return,默认就是{}块表达式的值
示例
- 定义一个方法,实现两个整形数值相加,返回相加后的结果
- 调用该方法
参考代码
scala> def add(a:Int, b:Int) = a + b
m1: (x: Int, y: Int)Int
scala> add(1,2)
res10: Int = 3
返回值类型推断
scala定义方法可以省略返回值,由scala自动推断返回值类型。这样方法定义后更加简洁。
[!DANGER]
定义递归方法,不能省略返回值类型
示例
定义递归方法(求阶乘)
10 * 9 * 8 * 7 * 6 * … * 1
参考代码
scala> def m2(x:Int) = {
| if(x<=1) 1
| else m2(x-1) * x
| }
<console>:13: error: recursive method m2 needs result type
else m2(x-1) * x
方法参数
scala中的方法参数,使用比较灵活。它支持以下几种类型的参数:
- 默认参数
- 带名参数
- 变长参数
默认参数
在定义方法时可以给参数定义一个默认值。
示例
- 定义一个计算两个值相加的方法,这两个值默认为0
- 调用该方法,不传任何参数
参考代码
// x,y带有默认值为0
def add(x:Int = 0, y:Int = 0) = x + y
add()
带名参数
在调用方法时,可以指定参数的名称来进行调用。
示例
- 定义一个计算两个值相加的方法,这两个值默认为0
- 调用该方法,只设置第一个参数的值
参考代码
def add(x:Int = 0, y:Int = 0) = x + y
add(x=1)
变长参数
如果方法的参数是不固定的,可以定义一个方法的参数是变长参数。
语法格式:
def 方法名(参数名:参数类型*):返回值类型 = {
方法体
}
[!NOTE]
在参数类型后面加一个
*
号,表示参数可以是0个或者多个
示例
- 定义一个计算若干个值相加的方法
- 调用方法,传入以下数据:1,2,3,4,5
参考代码
scala> def add(num:Int*) = num.sum
add: (num: Int*)Int
scala> add(1,2,3,4,5)
res1: Int = 15
方法和函数的区别
- 方法是隶属于类或者对象的,在运行时,它是加载到JVM的方法区中
- 可以将函数对象赋值给一个变量,在运行时,它是加载到JVM的堆内存中
- 函数是一个对象,继承自FunctionN(N<=22),函数对象有apply,curried,toString,tupled这些方法。方法则没有
- 函数最多支持22个参数,函数不能接收变长参数(), 如: val add = (x:Int) => x + y 不支持
- 带变长参数的方法可以转成函数 变成 带一个序列参数的function1 add _ 转函数为 Seq[Int] =>Int=《function1>
示例
方法无法赋值给变量
scala> def add(x:Int,y:Int)=x+y
add: (x: Int, y: Int)Int
scala> val a = add
<console>:12: error: missing argument list for method add
Unapplied methods are only converted to functions when a function type is expected.
You can make this conversion explicit by writing `add _` or `add(_,_)` instead of `add`.
val a = add
方法转换为函数
- 有时候需要将方法转换为函数,作为变量传递,就需要将方法转换为函数
- 使用
_
即可将方法转换为函数
示例
- 定义一个方法用来进行两个数相加
- 将该方法转换为一个函数,赋值给变量
参考代码
scala> def add(x:Int,y:Int)=x+y
add: (x: Int, y: Int)Int
scala> val a = add _
a: (Int, Int) => Int = <function2>