Scala 高阶函数自己总结
基础文档
之前自己总结的笔记,重点看 《Scala 中方法和函数底层Java 实现》
代码讲解
// HOFunc.scala
package com.abc.scala
object HOFunc {
// 一、高阶函数说明
/*
1. Scala 命名函数用def 定义,其底层实现跟Java 中定义方法一样,为了跟Scala 匿名函数区分也称其为"方法"
2. Scala 匿名函数通过赋值给变量,用变量名进行调用,其底层是一个对象,函数体定义写在该对象的apply 方法里
3. Scala 将输入或输出(即参数或返回值)的类型为函数的函数称为高阶函数(Higher Order Function)
4. Java 中没有函数指针的概念,所以不能直接将一个方法作为参数传给另一个方法,但对象可以作为参数传给方法
所以,Scala 中高阶函数的参数只能是底层为对象的匿名函数,即使传入了方法,Scala 也会自动将其转换为匿名函数
*/
// 二、高阶函数(参数为函数)
// def 高阶函数名(参数名: [参数类型 => 返回值类型 [, 其他参数类型]]): 高阶函数返回值 = { 高阶函数体定义 }
def hof_par2(op: String => String, arg1: String): Unit = {
println(op(arg1))
// 参数1 函数op (输入类型为String,输出类型为String)
// 参数2 字符串arg1 作为输入传给op 执行
// 高阶函数hof_par2 没有返回值即Unit
}
// 匿名函数只须写参数名和类型,不用写返回值类型,Scala 会根据 => 右边最后一行代码结果自动进行类型推断
val op1 = (name: String) => { "op1: hello " + name }
// 将函数传给高阶函数
hof_par2(op1, "ABC") // hello ABC
// 函数类型的参数简化(占位符 _ 语法糖)
// 传统方式将匿名函数传给高阶函数,有点繁琐,
hof_par2((name1:String) => { "Anonymous: hello " + name1}, "ABC")
/*
以下这条语句虽不符合Scala 语法,编译不通过,但很好地诠释了占位符 _ 的位置
hof_par2( (_) => { "Predigesting: hello " + _ }, "ABC")
由于高阶函数hof_par2 定义了输入函数的参数类型,所以Scala 可以推断出(_) 代表什么
又因为在 => 右边只出现了一个 _ 与 (_) 中的数量对应,所以多余的代码须将它们精简掉
即连同 => 及其左边的代码都去掉,只保留有效代码{ "Predigesting: hello " + _ }
根据Scala 的风格,只有一行语句时,括号() 或花括号{} 都是可以省略的,最终简化结果如下
*/
hof_par2( "Predigesting: hello " + _ , "ABC")
// 注意!高阶函数中如果传入的函数没有参数就相当于用{} 包起来的一个代码块,返回值是最后一行代码的结果
def hof_par0(op: => Unit): Unit = { op } // 定义高阶函数
val op0 = { println("No P and R") } // 定义无参函数(代码块)
hof_par0(op0) // 调用高阶函数
// 三、高阶函数(返回值为函数)
def hof_ret(prefix: String) = {
(name: String) => { println(prefix + name) } // 返回一个匿名函数
}
// 获取函数
val hr1 = hof_ret("VIP_")
// 调用该函数
hr1("BBB")
// 四、创建程序执行入口
def main(args: Array[String]): Unit = {
// 创建main 函数让以上代码在HOFunc$ 对象的构建函数中运行,详见Scala object 的底层分析笔记
}
}
编译运行
# 先将以上代码写入文件HOFunc.scala 然后执行
scalac HOFunc.scala && scala com.abc.scala.HOFunc