一. 函数的字面量语法
前要
在 Scala 中,def 和函数字面量是定义 “可执行逻辑” 的两种核心方式,但本质上分别对应方法(Method) 和函数(Function) ,二者在语义、使用场景和特性上有显著区别。
代码展示:定义函数的两种方式
object base1500 {
// 定义函数的方式一:def
def getSum(x:Int, y:Int):Int = {
x + y
}
// 定义函数的方式一:字面量
val getSum1 = (x:Int, y:Int) => {
x + y
}
def main(args: Array[String]): Unit = {
println( getSum(10,20)) // 30
println( getSum1(10,20)) // 30
}
}
def 方法与函数字面量的核心区别
| 维度 | def 方法(Method) | 函数字面量(Function) |
|---|---|---|
| 本质 | 类 / 对象的成员,依附于作用域 | 独立的值,FunctionN 特质的实例 |
| 是否为 “值” | 不是值,需通过 _ 转换为函数才能作为值传递 | 是值,可直接赋值、传递或返回 |
| 命名 | 必须有名称(方法名) | 本身匿名,需赋值给变量以复用 |
this 绑定 | 有 this 指针(指向所在类 / 对象) | 无 this 指针(若捕获外部 this 则继承) |
| 递归支持 | 直接通过方法名递归,需显式返回值类型 | 匿名函数无法直接递归,需借助 Y 组合子 |
| 常见场景 | 类 / 对象的成员逻辑、工具方法 | 高阶函数参数(如 map/filter)、回调逻辑 |
总结
- def 用于定义方法,是类 / 对象的成员,适合封装与特定作用域相关的逻辑。
- 函数字面量用于定义函数,是独立的值,适合需要传递、赋值的场景(如高阶函数、回调)。
- 二者在语法和语义上有明确区分,但可通过
_相互转换,共同支撑 Scala 的函数式编程特性。
定义
除了使用def之外的,另一种定义函数的方式,
它省略了def,函数名以及函数的返回值类型。
语法
var 变量 = (参数列表)=>{方法体}
方法
Scala的函数字面量的简化方式有两种方式:
- 第一种方式为:_(占位符)。如果函数中的参数在方法体中只使用了一次,可以用 _ 替换。
- 第二种方式为:只有一个表达式时,可以省略括号。
代码展示:函数字面量的简化写法
object base1501 {
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)) // 30
println( getSum1(10,20)) // 30
println( getSum2(10,20)) // 30
println( getSum3(10,20)) // 30
}
}
二. 把函数作为参数💕前景提要💕
代码展示
object base1502 {
/*
* 把一个函数 当做参数 传递给另一个函数
* */
// 定义两个字面量函数。(Int, Int) => Int 看成一种数据类型
val f1:(Int, Int) => Int = _ + _
// val a: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)) // 30
println( test(f2, 10, 20)) // 200
}
}
代码分析
- 定义字面量函数
val f1: (Int, Int) => Int = _ + _:定义了一个函数f1,它接受两个Int类型的参数,返回它们的和。这里的_ + _是一种简洁的写法,等价于(a: Int, b: Int) => a + b。val f2: (Int, Int) => Int = _ * _:定义了函数f2,接受两个Int类型参数,返回它们的积,等价于(a: Int, b: Int) => a * b。
- 定义 test 函数
def test(fn: (Int, Int) => Int, x: Int, y: Int): Int = { fn(x, y) }:test函数有三个参数,第一个参数fn是一个函数类型(要求传入的函数接受两个Int参数并返回Int),后两个参数x和y是Int类型。函数体是调用传入的fn函数,并用x和y作为参数,最后返回调用结果。
- main 方法(程序入口)
def main(args: Array[String]): Unit = { ... }:这是 Scala 程序的主入口方法。println(test(f1, 10, 20)):调用test函数,传入f1(做加法的函数)、10和20,执行后会计算10 + 20,输出30。println(test(f2, 10, 20)):调用test函数,传入f2(做乘法的函数)、10和20,执行后会计算10 * 20,输出200。
三. Scala部分应用函数
定义
如果一个函数包含多个参数,对该函数传递部分参数使得这个函数返回一个函数,那么这种函数叫做部分应用函数。
代码展示
object base1506 {
def getSum(a: Int, b: Int, c: Int): Int = {
a + b + c
}
def main(args: Array[String]): Unit = {
println(getSum(10, 20, 30)) // 60
val t = getSum(10, 20, _) // t 就是部分应用函数!
val t1 = getSum(_, 20, _) // t 就是部分应用函数!
println(t(50)) // 80
println(t1(20, 50)) // 90
}
}
注意: 部分应用函数:
- 如果一个函数需要3个参数,而我们只给了2个参数,会怎么样?
会报错:not enough arguments 可以通过补充参数的默认值来优化
def getSum(a:Int, b:Int, c:Int = 0):Int = {
a + b + c
}
def main(args: Array[String]): Unit = {
println( getSum(10, 20, 30) )
println( getSum(10, 20) )
}
- 如果一个函数需要 3 个参数,而我们只给了 2 个参数,另一个用 _ 来替代,会怎么样?
此时,函数
不报错,能正常执行。 它的返回值是一个函数:部分应用函数