函数的定义

107 阅读2分钟

在 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 允许简化定义:

  1. 单行函数体:可省略花括号 {}

    def multiply(x: Int, y: Int): Int = x * y  // 直接返回表达式结果
    
  2. 返回类型推断:当函数体只有一行且类型明确时,可省略返回类型(递归函数除外,必须显式声明返回类型)

    def subtract(a: Int, b: Int) = a - b  // 编译器自动推断返回类型为 Int
    
  3. 无参数函数

    • 若函数无参数,可省略括号(调用时也无需括号);
    • 若定义时带空括号,调用时可带或不带括号。
    def greet(): String = "Hello"  // 带空括号定义
    def welcome = "Welcome"        // 不带括号定义
    
    println(greet())   // 输出:Hello
    println(greet)     // 输出:Hello(允许省略括号)
    println(welcome)   // 输出:Welcome(必须不带括号调用)
    // println(welcome())  // 错误:无参数且定义时无括号,调用不能加括号
    
  4. 无返回值函数(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)

四、特殊函数形式

  1. 带默认参数的函数:参数可指定默认值,调用时可省略该参数

    scala

    def greet(name: String = "Guest"): String = s"Hello, $name!"
    
    println(greet("Alice"))  // 输出:Hello, Alice!
    println(greet())         // 输出:Hello, Guest!(使用默认值)
    
  2. 可变参数函数:参数个数可变(类似数组),用 * 标记

    scala

    def sum(numbers: Int*): Int = {
      numbers.sum  // 可变参数本质是 Seq,可调用 sum 方法
    }
    
    println(sum(1, 2, 3))    // 输出:6
    println(sum(10, 20, 30, 40))  // 输出:100
    
  3. 递归函数:函数自身调用,必须显式声明返回类型

    scala

    // 计算阶乘(n! = n × (n-1) × ... × 1)
    def factorial(n: Int): Int = {
      if (n <= 1) 1
      else n * factorial(n - 1)  // 递归调用
    }
    
    println(factorial(5))  // 输出:120