在 Scala 中,函数是一等公民(first-class citizen),可以像变量一样被传递、赋值或作为参数 / 返回值使用。函数的定义有多种形式,核心是 “输入参数 → 处理逻辑 → 返回结果” 的映射关系。
一、基本定义格式(具名函数)
最常见的函数定义形式,使用 def 关键字声明,包含函数名、参数列表、返回类型(可选,可由编译器推断)和函数体。
完整格式:
def 函数名(参数名1: 参数类型1, 参数名2: 参数类型2, ...): 返回类型 = {
// 函数体(最后一行表达式的结果即为返回值,无需显式写 return)
}
示例:
// 定义一个计算两数之和的函数
def add(a: Int, b: Int): Int = {
a + b // 最后一行表达式的结果作为返回值
}
// 调用函数
println(add(2, 3)) // 输出:5
二、简化形式
根据函数体的复杂度,Scala 允许简化定义:
-
单行函数体:可省略花括号
{}def multiply(x: Int, y: Int): Int = x * y // 直接返回表达式结果 -
返回类型推断:当函数体只有一行且类型明确时,可省略返回类型(递归函数除外,必须显式声明返回类型)
def subtract(a: Int, b: Int) = a - b // 编译器自动推断返回类型为 Int -
无参数函数:
- 若函数无参数,可省略括号(调用时也无需括号);
- 若定义时带空括号,调用时可带或不带括号。
def greet(): String = "Hello" // 带空括号定义 def welcome = "Welcome" // 不带括号定义 println(greet()) // 输出:Hello println(greet) // 输出:Hello(允许省略括号) println(welcome) // 输出:Welcome(必须不带括号调用) // println(welcome()) // 错误:无参数且定义时无括号,调用不能加括号 -
无返回值函数(Unit 类型) :若函数无实际返回值(仅执行副作用,如打印),返回类型为
Unit(类似 Java 的void),可省略返回类型和=// 完整写法 def printMessage(msg: String): Unit = { println(msg) } // 简化写法(省略 Unit 和 =) def logInfo(info: String) { println(s"[INFO] $info") }
三、匿名函数(Lambda 表达式)
没有名称的函数,通常用于临时传递逻辑(如作为高阶函数的参数),格式为:(参数名1: 类型1, 参数名2: 类型2, ...) => 表达式
示例:
// 定义一个匿名函数(计算两数乘积)
val multiply = (x: Int, y: Int) => x * y // 赋值给变量,通过变量调用
println(multiply(3, 4)) // 输出:12
// 作为高阶函数参数(如集合的 map 方法)
val numbers = List(1, 2, 3)
val doubled = numbers.map(n => n * 2) // 匿名函数 n => n*2 作为参数
println(doubled) // 输出:List(2, 4, 6)
四、特殊函数形式
-
带默认参数的函数:参数可指定默认值,调用时可省略该参数
scala
def greet(name: String = "Guest"): String = s"Hello, $name!" println(greet("Alice")) // 输出:Hello, Alice! println(greet()) // 输出:Hello, Guest!(使用默认值) -
可变参数函数:参数个数可变(类似数组),用
*标记scala
def sum(numbers: Int*): Int = { numbers.sum // 可变参数本质是 Seq,可调用 sum 方法 } println(sum(1, 2, 3)) // 输出:6 println(sum(10, 20, 30, 40)) // 输出:100 -
递归函数:函数自身调用,必须显式声明返回类型
scala
// 计算阶乘(n! = n × (n-1) × ... × 1) def factorial(n: Int): Int = { if (n <= 1) 1 else n * factorial(n - 1) // 递归调用 } println(factorial(5)) // 输出:120