高阶函数

77 阅读4分钟

Scala 高阶函数(核心知识 + 实战场景)

Scala 作为函数式编程语言,高阶函数(Higher-Order Function)  是核心特性之一。其定义是:能够接收函数作为参数,或返回函数作为结果的函数

高阶函数的核心价值是「抽象通用逻辑、减少重复代码」,结合 Scala 的匿名函数、闭包等特性,能极大提升代码简洁性和灵活性。以下从「基础概念 → 核心用法 → 实战场景 → 底层原理」逐步讲解,覆盖日常开发 99% 场景。

一、先明确:高阶函数的核心前提

要理解高阶函数,需先掌握 2 个基础概念:

  1. 函数是 “一等公民” :Scala 中函数可以像变量一样,作为参数传递、作为返回值、赋值给变量(这是高阶函数的基础)。

  2. 函数类型:函数有明确的类型签名,格式为 (参数类型1, 参数类型2, ...) => 返回值类型。例如:

    • (Int, Int) => Int:接收两个 Int 参数,返回 Int 的函数;
    • String => Unit:接收一个 String 参数,无返回值(Unit)的函数;
    • () => Int:无参数,返回 Int 的函数(空参函数)。

二、高阶函数的两大核心形式

1. 形式一:接收函数作为参数(最常用)

这是日常开发中最频繁使用的场景,核心是「将通用逻辑抽象为函数参数」,避免重复代码。

示例 1:自定义简单高阶函数(抽象 “运算逻辑”)

需求:实现一个函数,接收两个 Int 和一个 “运算函数”,返回运算结果。

// 高阶函数:接收 (Int, Int) => Int 类型的函数作为参数
def calculate(a: Int, b: Int, op: (Int, Int) => Int): Int = {
  op(a, b) // 调用传入的函数参数
}

// 定义具体的运算函数(也可以用匿名函数直接传入)
def add(x: Int, y: Int): Int = x + y
def multiply(x: Int, y: Int): Int = x * y

// 调用高阶函数:传入具体函数
val sum = calculate(3, 5, add)        // 3+5=8
val product = calculate(3, 5, multiply) // 3*5=15

// 更简洁:直接传入匿名函数(无需定义单独函数)
val subtract = calculate(10, 4, (x, y) => x - y) // 10-4=6
val divide = calculate(8, 2, (x, y) => x / y)    // 8/2=4

println(sum)      // 8
println(product)  // 15
println(subtract) // 6
println(divide)   // 4

核心价值:calculate 函数抽象了 “接收两个数并运算” 的通用逻辑,具体运算规则(加、减、乘、除)通过函数参数传入,实现 “逻辑复用 + 灵活扩展”。

示例 2:结合集合的高阶函数(日常最高频)

Scala 集合(ListMapSeq 等)内置了大量高阶函数(如 mapfilterforeachreduce),本质都是 “接收函数作为参数”:

val numbers = List(1, 2, 3, 4, 5)

// 1. map:对每个元素应用函数,返回新集合((Int) => T 类型参数)
val doubled = numbers.map(x => x * 2) // List(2,4,6,8,10)
val strNumbers = numbers.map(x => s"数字:$x") // List(数字:1, 数字:2, ...)

// 2. filter:筛选满足条件的元素((Int) => Boolean 类型参数)
val evenNumbers = numbers.filter(x => x % 2 == 0) // List(2,4)
val bigNumbers = numbers.filter(x => x > 3) // List(4,5)

// 3. foreach:遍历每个元素执行副作用((Int) => Unit 类型参数)
numbers.foreach(x => println(s"元素:$x")) // 打印每个元素

// 4. reduce:聚合元素((Int, Int) => Int 类型参数)
val total = numbers.reduce((x, y) => x + y) // 1+2+3+4+5=15
val max = numbers.reduce((x, y) => if (x > y) x else y) // 5

println(doubled)      // List(2, 4, 6, 8, 10)
println(evenNumbers)  // List(2, 4)
println(total)        // 15
println(max)          // 5

简化语法:如果函数参数是 “单个参数且只使用一次”,可以用 _ 替代参数名(占位符语法):

scala

numbers.map(_ * 2) // 等价于 x => x * 2
numbers.filter(_ % 2 == 0) // 等价于 x => x % 2 == 0
numbers.reduce(_ + _) // 等价于 (x, y) => x + y(第一个 _ 代表 x,第二个 _ 代表 y)

2. 形式二:返回函数作为结果

高阶函数可以返回一个函数,核心是「延迟执行逻辑」或「动态生成函数」(根据输入参数动态创建不同逻辑的函数)。

示例 1:动态生成 “过滤函数”

需求:生成一个 “判断数字是否大于 N” 的函数,N 由输入参数指定。

// 高阶函数:接收 Int 参数 N,返回 (Int) => Boolean 类型的函数
def createGreaterFilter(N: Int): Int => Boolean = {
  // 返回匿名函数:判断输入 x 是否大于 N
  (x: Int) => x > N
}

// 生成“大于 3”的过滤函数
val greaterThan3 = createGreaterFilter(3)
// 生成“大于 5”的过滤函数
val greaterThan5 = createGreaterFilter(5)

// 使用生成的函数
val numbers = List(1, 2, 3, 4, 5, 6)
val filtered1 = numbers.filter(greaterThan3) // List(4,5,6)
val filtered2 = numbers.filter(greaterThan5) // List(6)

println(filtered1) // List(4, 5, 6)
println(filtered2) // List(6)
示例 2:延迟执行的 “运算函数”

需求:生成一个 “固定因子的乘法函数”,因子由输入参数指定,后续可多次使用。

scala

// 高阶函数:接收因子 factor,返回 (Int) => Int 类型的函数
def createMultiplier(factor: Int): Int => Int = {
  (x: Int) => x * factor // 闭包:返回的函数引用了外部变量 factor
}

// 生成“乘以 2”的函数
val multiplyBy2 = createMultiplier(2)
// 生成“乘以 10”的函数
val multiplyBy10 = createMultiplier(10)

// 多次使用生成的函数
println(multiplyBy2(5))  // 5*2=10
println(multiplyBy2(8))  // 8*2=16
println(multiplyBy10(3)) // 3*10=30

关键:返回的函数引用了外部变量 factor,这是「闭包」的典型场景(下文会详细讲解)。