10.21

55 阅读3分钟
  1. 使用 def 关键字定义函数 getSum
  2. 使用函数字面量(匿名函数赋值给变量)定义 getSum1
object base44 {
  /*
   * 函数字面量
   * 另一种定义函数的方式
   */

  // 定义函数的方式一: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))
    println(getSum1(10, 20))
  }
}

image.png

  1. 基础字面量形式(getSum :完整保留了函数字面量的结构,用 => 连接参数列表和函数体,函数体用 {} 包裹单条语句(这里可省略)。
  2. 省略大括号(getSum1 :当函数体只有一行代码时,{} 可以直接省略,简化为 (参数) => 表达式 的形式。
  3. 使用 _ 占位符(getSum2 :用 _ 代替参数名,同时显式指定参数类型(_: Int),多个 _ 按顺序对应不同参数,适合简单表达式。
  4. 类型推断下的 _ 占位符(getSum3 :提前指定变量类型为 (Int, Int) => Int(表示接收两个 Int 并返回 Int 的函数),此时 _ 无需显式声明类型,Scala 会自动推断,写法更简洁。
object base45 {
  /*
  函数字面量的简化写法
  * 1. 代码只有一句,省略 {}
  * 2. _ 占位符来替换形参
  */

  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))
    println(getSum1(10, 20))
    println(getSum2(10, 20))
    println(getSum3(10, 20))
  }
}

image.png

1. 定义 “函数类型” 的变量

scala

val f1: (Int, Int) => Int = _ + _
val f2: (Int, Int) => Int = _ * _
  • (Int, Int) => Int 是一种函数类型,表示:“接收两个 Int 参数,返回一个 Int 结果的函数”。

  • _ + _ 和 _ * _ 是函数字面量的简化写法

    • 第一个 _ 代表第一个参数,第二个 _ 代表第二个参数;
    • f1 实现 “两数相加”,f2 实现 “两数相乘”。

2. 定义 “接收函数作为参数” 的函数(高阶函数)

scala

def test(fn: (Int, Int) => Int, x: Int, y: Int): Int = {
  fn(x, y)
}
  • test 是一个高阶函数:它的第一个参数 fn 的类型是 (Int, Int) => Int(即 “函数类型”),表示 fn 本身是一个函数。
  • 逻辑:调用传入的函数 fn,并把 xy 作为参数传给 fn,最终返回 fn(x, y) 的结果。

3. 主方法调用(验证逻辑)

scala

def main(args: Array[String]): Unit = {
  println(test(f1, 10, 20))  // 输出 30(10 + 20)
  println(test(f2, 10, 20))  // 输出 200(10 * 20)
}
  • 第一次调用 test(f1, 10, 20):把 f1(加法函数)传给 testtest 内部执行 f1(10, 20),即 10 + 20,结果为 30
  • 第二次调用 test(f2, 10, 20):把 f2(乘法函数)传给 testtest 内部执行 f2(10, 20),即 10 * 20,结果为 200

核心知识点

  • 函数是 “一等公民” :Scala 中函数可以像普通变量一样,被赋值、传递、作为参数传入其他函数。
  • 高阶函数:接收 “函数” 作为参数,或返回 “函数” 的函数,是函数式编程的重要特性。
  • 函数字面量简化:用 _ 代替参数名,让函数定义更简洁(需保证类型可推断)。
object base46 {
  /*
   * 把一个函数 当做参数 传递给另一个函数
   */

  // 定义两个字面量函数。(Int, Int) => Int 看成一种数据类型
  val f1: (Int, Int) => Int = _ + _
  // val a:Int = 1
  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))
    println(test(f2, 10, 20))
  }
}

image.png