在Scala中,函数是 “一等公民” ,就是和 Int,String等基本类型一样的地位。
函数
表达式是可以计算的语句。
函数是带有参数的表达式。
可以定义一个匿名函数(没有名字),用来直接作为 参数,传入高阶函数。
(x: Int) => x + 1
也可以函数命名,函数可以带一个或多个参数。
val add = (x: Int, y: Int) => x + y
方法
方法的表现和行为和函数非常类似,但是它们之间有一些关键的差别。
方法由def关键字定义。def后面跟着一个名字、参数列表、返回类型和方法体。
方法可以接受 一个或多个 参数列表。还可以没有参数列表。
def addThenMultiply(x: Int, y: Int)(multiplier: Int): Int = (x + y) * multiplier
方法也可以有多行的表达式。
def getSquareString(input: Double): String = {
val square = input * input
square.toString
}
方法体的最后一个表达式就是方法的返回值。(Scala中也有一个return关键字,但是很少使用)
高阶函数
高阶函数是指使用其他函数作为参数、或者返回一个函数作为结果的函数。
我们约定,使用函数值作为参数,或者返回值为函数值的“函数”和“方法”,均称之为“高阶函数”。
我们可以使用匿名函数,直接作为参数传递给map:
val salaries = Seq(20000, 70000, 40000)
val newSalaries = salaries.map(x => x * 2) // List(40000, 140000, 80000)
注意在上述示例中x没有被显式声明为Int类型,这是因为编译器能够根据map函数期望的类型推断出x的类型。对于上述代码,一种更惯用的写法为:
val salaries = Seq(20000, 70000, 40000)
val newSalaries = salaries.map(_ * 2)
既然Scala编译器已经知道了参数的类型(一个单独的Int),你可以只给出函数的右半部分,不过需要使用_代替参数名(在上一个例子中是x)
你同样可以传入一个对象方法作为高阶函数的参数,这是因为Scala编译器会将方法强制转换为一个函数。
对于 有多个参数列表的方法,在传入高阶函数时,如果只指定了某前几个参数列表,那么后面的几个参数列表会作为 被强制转换为的函数需要提供的参数列表。
嵌套方法
在Scala中可以嵌套定义方法。
在一个方法中,定义另一个方法,并可以调用。
例如以下对象提供了一个factorial方法来计算给定数值的阶乘:
def factorial(x: Int): Int = {
def fact(x: Int, accumulator: Int): Int = {
if (x <= 1) accumulator
else fact(x - 1, x * accumulator)
}
fact(x, 1)
}
println("Factorial of 2: " + factorial(2))
println("Factorial of 3: " + factorial(3))