1. 函数字面量
在 Scala 中,函数字面量(Function Literal)和部分应用函数(Partially Applied Function)是函数式编程的重要概念
(一)函数的字面量语法
[讲]除了使用def之外的,另一种定义函数的方式
语法:var 变量 = (参数列表)=>{方法体}
它省略了def,函数名以及函数的返回值类型。
核心特点:
- 匿名性:没有函数名,可直接使用或赋值给变量
- 可作为值传递:能作为参数传入其他函数,或作为返回值
// 定义
val sum1 = (x:Int, y:Int)=>{x+y}
// 调用
var s = sum1(10,34)
[简化写法]
Scala的函数字面量的简化方式有两种方式:
第一种方式为:_(占位符)。如果函数中的参数在方法体中只使用了一次,可以用_替换。
第二种方式为:只有一个表达式时,可以省略括号。
val sum1 = (x:Int, y:Int) =>{x+y}
val sum2 = (x:Int, y:Int) => x+y
val sum3:(Int, Int)=>Int = _ + _
(二)函数作为参数
[讲] 某个函数的参数是函数
[码] 定义一个接收函数作为参数的函数def a(f:()=>Unit)={},其中函数的类型()=>Unit部分()为函数的参数,Unit为函数的返回值。通过定义字面量传递值时,字面量必须和函数的类型匹配。
// 奶茶店1
var add = (x:Int, y:Int) => x + y
// 咖啡店1
var mul = (x:Int, y:Int) => x*y
// 定义一个函数。它的特点是:第一个参数的类型是函数!
// 美团
var op = (fn: (Int, Int)=>Int, a:Int, b:Int) => {
fn(a,b)
}
// add(100, 200) // 直接去奶茶店买
println( op(add, 100, 200) )
println( op(mul, 100, 200) )
(三)把函数作为返回值
函数的返回值是一个函数 代码:
def main(args: Array[String]): Unit = {
// 函数f 的返回值就是一个函数
var f = (x:Int) => {
// println(x)
// var f1 = (y:Int) => x + y
// f1 // 返回值是一个函数
(y:Int) => x + y
}
var s = f(2) // s 是一个函数
var res = s(10)
println(res)
}
(四)Scala的函数的闭包
闭包是:一个函数连同该函数的非局部变量的一个引用环境。
函数和变量的定义要在同一个作用域,函数可以引用已经创建的变量,函数可以同值一样被传递和应用,当执行函数时该函数仍然引用着变量。
代码:
object ClosureExample2 {
def makeAdder(adder: Int): Int => Int = {
(x: Int) => x + adder
}
def main(args: Array[String]): Unit = {
val addFive = makeAdder(5)
val addTen = makeAdder(10)
println(addFive(3)) // 输出 8
println(addTen(3)) // 输出 13
}
}
(五)函数的柯里化格式定义
定义函数的另一种格式
柯里化的定义语法为:
def 函数名(参数列表1)(参数列表2)...(参数列表n):type={
方法体
}
代码:
// 正常定义
def add(x:Int,y:Int)=x+y
println(add(1,2))
// 柯里化定义:一个参数一个括号,参数单独写
def add(x:Int)(y:Int) = x + y
println(add(1)(2))
2. 部分应用函数
部分应用函数是指对一个多参数函数,只传入部分参数,而不是全部参数,得到的一个新函数(需要后续传入剩余参数才能执行)。
(六)Scala部分应用函数
如果一个函数包含多个参数,对该函数传递部分参数使得这个函数返回一个函数,那么这种函数叫做部分应用函数。 代码:
// 定义普通函数
def mutlti(x:Int, y:Int, z:Int) = {
println(s"$x, $y, $z")
x * y * z
}
// 传入部分参数,返回部分函数
var f1 = mutlti(2, _, _)
// 调用部分函数
println( f1(10, 5) )
核心特点:
- 基于已有函数,固定部分参数,保留剩余参数的输入能力
- 语法上用下划线 (_) 表示未传入的参数
案例:
// 定义一个需要3个参数的函数
def calculate(a: Int, b: Int, c: Int): Int = a + b * c
// 1. 部分应用:只传入第一个参数,保留后两个参数
val partial1: (Int, Int) => Int = calculate(10, _, _) // 固定a=10,需传入b和c
println(partial1(2, 3)) // 等价于calculate(10,2,3),输出:10 + 2*3 = 16
// 2. 部分应用:传入前两个参数,保留最后一个参数
val partial2: Int => Int = calculate(5, 2, _) // 固定a=5, b=2,需传入c
println(partial2(4)) // 等价于calculate(5,2,4),输出:5 + 2*4 = 13
// 3. 部分应用:不传入任何参数(保留所有参数)
val partial3: (Int, Int, Int) => Int = calculate(_, _, _) // 等价于原函数
println(partial3(1, 2, 3)) // 输出:1 + 2*3 = 7
// 4. 在高阶函数中使用部分应用
def log(time: String, message: String): Unit = {
println(s"[$time] $message")
}
val todayLog: String => Unit = log("2025-10-20", _) // 固定time,保留message
todayLog("系统启动") // 输出:[2025-10-20] 系统启动
todayLog("任务完成") // 输出:[2025-10-20] 任务完成