Scala函数变量、=>与_的用法疑问及语法解析
一、为什么示例A的占位符_生效,示例B的不行?
先看两个示例代码:
- 示例A:
val sumFunction: (Int,Int) => Int = _ + _ - 示例B:
val mulFunc = (a: Int, b: Int) => _ * _
示例A的逻辑
这里的(Int,Int) => Int是变量的类型标注,明确告诉编译器sumFunction是一个「接受两个Int参数、返回Int」的函数。此时_ + _是Scala的占位符语法,第一个_对应函数的第一个参数,第二个_对应第二个参数——编译器能通过变量的类型上下文,自动把占位符映射到函数参数上,最终等价于(x: Int, y: Int) => x + y。
示例B的问题
示例B里的(a: Int, b: Int) => ...是完整的匿名函数定义,箭头=>左边已经显式声明了参数a和b,箭头右侧是函数体。而_ * _的占位符语法,只有在没有显式写出参数列表的场景下才能使用——编译器在这里无法推断_对应的是什么参数(毕竟你已经定义了a和b),所以会报错。正确写法应该直接引用已声明的参数:val mulFunc = (a: Int, b: Int) => a * b。
二、示例C和D中=>的用法差异
再看两个示例代码:
- 示例C:
val sumFunction2: (a: Int, b: Int) => Int = _ + _ - 示例D:
val mulFunc2 = (a: Int, b: Int) => a * b
示例C中的=>:函数类型标记
这里的(a: Int, b: Int) => Int是函数类型的定义,属于变量sumFunction2的类型标注。=>用来描述函数的“输入输出关系”——意思是「接受类型为Int的参数a和b,返回Int类型的值」。后面的_ + _是函数的具体实现,通过占位符语法简写。
示例D中的=>:匿名函数分隔符
这里的(a: Int, b: Int) => a * b是完整的匿名函数,=>的作用是分隔参数列表和函数体——左侧是函数要接收的参数,右侧是参数要执行的逻辑。整个表达式直接定义了函数的参数和实现,不需要额外类型标注(编译器可自动推断返回类型)。
内容的提问来源于stack exchange,提问作者Bibhuti Mohapatra

