Scala 函数进阶涵盖高阶函数、闭包、柯里化等核心概念。高阶函数可将函数作为参数或返回值,如 map 方法接收匿名函数处理集合。闭包允许函数捕获外部作用域变量,延长其生命周期,例如在循环中生成带状态的函数。柯里化将多参数函数转为单参数函数链,通过 def add(x: Int)(y: Int) = x + y 形式实现,便于参数分步传递和类型推断。
此外,部分应用函数通过下划线固定部分参数生成新函数,如 val add5 = add(5)_。隐式函数可自动转换类型,增强代码灵活性。函数组合(compose/andThen)能将多个函数串联执行,提升代码复用性。这些特性使 Scala 函数式编程更灵活,支持模块化和简洁表达复杂逻辑。
1.函数的字面量语法
除了使用def之外的,另一种定义函数的方式
语法:
var 变量 = (参数列表)=>{方法体}
它省略了def,函数名以及函数的返回值类型。
代码如下:
object base44 {
/*
* 函数字面量
* 另一种定义函数的方式
* */
//定义函数的方式一:def
def getSum(x:Int,y:Int):Int = {
x + y
}
def getSum1= (x:Int,y:Int) =>{
x + y
}
def main(args: Array[String]): Unit = {
println(getSum(10,20))
println(getSum1(10,20))
}
}
运行结果如下:
// 定义
val sum1 = (x:Int, y:Int)=>{x+y}
// 调用
var s = sum1(10,34)
简化写法
Scala的函数字面量的简化方式有两种方式:
第一种方式为:_(占位符)。如果函数中的参数在方法体中只使用了一次,可以用_替换。
第二种方式为:只有一个表达式时,可以省略括号。
object base45 {
/*
*函数字面量的简化写法
* 1.代码只有一句,省略{}
* 2.—占位符表示形参
*/
//
val getSum = (x:Int , y:Int) => {
x + y
}
//省略{}
val getSum1 = (x:Int , y:Int) => x + y
//使用_代替形参
val getSum2 = (_:Int) + (_:Int)
//使用_代替形参。(Int,Int)=>Int 就是getSum3的类型
val getSum3:(Int,Int) => Int = _ + _
def main(args: Array[String]): Unit = {
println(getSum(10,20))
println(getSum1(10,20))
println(getSum2(10,20))
println(getSum3(10,20))
}
}
2.函数作为参数
某个函数的参数是函数
在 Scala 中,允许函数的参数是另一个函数(这类函数称为高阶函数),这是函数式编程的核心特性之一。这种设计让代码更灵活、模块化,能轻松实现逻辑复用和行为定制。以下结合具体示例详细解释:
A. 核心概念
- 函数类型:函数在 Scala 中是 “一等公民”,可以像变量一样传递。函数的类型由参数类型和返回值类型共同定义,格式为:
(参数类型1, 参数类型2, ...) => 返回值类型。例如:(Int, Int) => Int表示 “接收两个 Int 参数、返回 Int 的函数”。 - 高阶函数:接收函数作为参数,或返回函数作为结果的函数。本文重点讨论 “参数是函数” 的情况。
B. 示例解析
object base46 {
/*
把一个函数 当参数 传递给另一个函数
*/
// 定义两个字面量函数。(Int, Int) => Int 看成一种数据类型
val f1: (Int, Int) => Int = _ + _
val f2: (Int, Int) => Int = _ * _
// 定义一个函数,它有三个参数
// 参数1:类型是 (Int,Int)=>Int 。它表示这里需要一个函数
def test(fn: (Int, Int) => Int, x: Int, y: Int): Int = {
fn(x, y)
}
def main(args: Array[String]): Unit = {
println(test(f1, 10, 20) + " === " + f1(10, 20))
println(test(f2, 10, 20))
}
}
C. 关键细节
-
函数参数的声明:在高阶函数的参数列表中,需明确指定函数参数的类型(如
func: (Int, Int) => Int),表示 “此处需要一个符合该类型的函数”。 -
函数的传递方式:
- 可以传递已定义的函数变量(如示例中的
add、multiply)。 - 可以直接传递匿名函数(如
(a, b) => a - b),简化代码。
- 可以传递已定义的函数变量(如示例中的
-
函数的调用:在高阶函数内部,通过参数名(如
func)调用传入的函数,并传入所需参数(如func(x, y))。
D. 应用场景
- 逻辑复用:将通用逻辑(如遍历集合)封装为高阶函数,通过传入不同的处理函数实现多样化需求(例如
List.map(f)中,map是高阶函数,f是处理每个元素的函数)。 - 行为定制:允许调用者动态指定函数的核心逻辑(如排序算法中,通过传入比较函数定制排序规则)。
- 简化代码:避免重复编写相似逻辑,用匿名函数快速传递简单逻辑。
通过函数作为参数,Scala 实现了 “用代码定义代码的行为”,大幅提升了代码的灵活性和表达力,是函数式编程思想的典型体现。
3.Scala部分应用函数
如果一个函数包含多个参数,对该函数传递部分参数使得这个函数返回一个函数,那么这种函数叫做部分应用函数
代码如下:
object base47 {
def getSum(a: Int, b: Int, c: Int): Int = {
a + b + c
}
def main(args: Array[String]): Unit = {
println(getSum(10, 20, 30))
val t = getSum(10, 20, _) // 部分应用函数
val t1 = getSum(20, 20, _) // 部分应用函数
println(t(30))
println(t1(50))
}
}