(六)Scala高阶函数【从普通函数到高阶函数的详细过程】

Scala高阶函数官方文档

方法(Method)的官方文档:https://docs.scala-lang.org/scala3/book/methods-intro.html 【点next进入下一步】
函数(Function)的官方文档:https://docs.scala-lang.org/scala3/book/fun-intro.html【点next进入下一步】

一.函数 & 方法定义

  • 方法定义:
    • def 方法名(参数1:参数1类型, 参数2:参数2类型…):返回值类型 = { 函数体 }
scala> def f3(a:Int,b:Int):Int = a + b
f3: (a: Int, b: Int)Int

方法可以嵌套定义;
两个方法名称相同时,就近调用。

// 函数
object FunctionApp {
   
 def main(args: Array[String]): Unit = {
   
   def sayHi(name:String) ={
   
     println(s"Hi, $name")
   }
   sayHi("Scala,1")       // 就近调用sayHi方法, 输出结果:Hi, Scala,1
   FunctionApp.sayHi("Scala,2")    // 如果想调用外部定义的sayHi方法,输出结果:Hello, Scala,2
   }

 def sayHi(name:String) ={
   
   println(s"Hello, $name")
 }
 sayHi("Flink,3")    // 就近调用sayHi方法, 输出结果:Hello, Flink,3
}
/*
* 输出结果先后顺序:
	Hello, Flink,3
	Hi, Scala,1
	Hello, Scala,2
*/
  • 函数定义【下面函数的定义有点复杂,不用记忆】:

    • 1)var/val 函数名 = (参数列表) => { 函数体 }
    • 2)var/val 函数名:(参数1类型, 参数2类型…) => 返回值类型 = (参数1:参数1类型, 参数2:参数2类型…) => { 函数体 }

    1)和 2)中函数的定义,最后都等价于**{函数体}**中的结果,如果只写 {函数体},就是匿名函数

// 函数两种定义,其实本质是一样的。都(Int,Int) => Int 
scala> val f1 = (a:Int, b:Int)=> {
    a + b }
f1: (Int, Int) => Int = $$Lambda$1032/378196591@656a3d6b

scala> val f2:(Int,Int) => Int = (a,b) => {
    a + b }
f2: (Int, Int) => Int = $$Lambda$1048/517991921@251a90ce
===============================================
//上面两个都是这个匿名函数/匿名方法: (a,b)=>a+b
// 调用都是:f1(2,3) 和 f2(2,3)

二.函数和方法的相互转换

  • 方法是一个特殊的函数(一等公民)两者之间相互调用,转换
    • 函数转换成方法:直接转换
    • 方法转换成函数:
      • 1)= 方法名 _ (注意_前面有个空格)
      • 2) ( _, _) 括号中有几个参数,就有几个下横线
      • 3)直接转换,val 函数名:(参数1类型, 参数2类型…) => 返回值类型 = 方法名
// 函数转换成方法:直接转换
val f1Fun = (a:Int, b:Int) => {
    a + b }
def fun = f1Fun
println(fun)     // 输出结果:FunctionApp$$$Lambda$6/312116338@1b0375b3
println(fun(3,4))// 输出结果:7
// 方法转函数的3种方式
def f2(a:Int,b:Int):Int = {
    a + b }
 
val f2Fun = f2 _        // 这里值需要写 空格&一个下划线
val f3Fun = f2(_,_)     // 如果方法f2有几个参数,括号中需要写几个_
val f4Fun:(Int,Int)=>Int = f2 // 前面已经指定了函数的返回值类型((Int,Int)=>Int),后面就可以不用下划线了

println(f2Fun)      // 输出结果:LamdaApp$$$Lambda$17/13648335@2f7c7260
println(f2Fun(5,6)) // 函数进行调用,输出结果:11
println(f3Fun)      // 输出结果:LamdaApp$$$Lambda$18/312116338@2d209079
println(f3Fun(5,6))  // 函数进行调用,输出结果:11
println(f4Fun)      // 输出结果:LamdaApp$$$Lambda$19/453211571@6bdf28bb
println(f4Fun(5,6))  // 函数进行调用,输出结果:11

三.函数的参数 & 返回值

  1. 无参的函数/方法
  2. 有固定参数的函数/方法
  3. 可变参数的函数/方法 【如果有固定参数, 可变参数放在参数列表最后】
  4. 默认值参数
// 1. 无参的函数/方法
def fun1() = {
    println("hello,welcome to Scala") }
fun1()             // 输出结果:hello,welcome to Scala
// 2. 有固定参数的函数/方法
def fun2(a: Int, b: Int) = {
    println( a + b)  }
fun2(3,4)         // 输出结果:7
// 3. 可变参数的函数/方法
def fun31(b: Int*) = {
    println(b) }
def fun32(a: Int, b: Int*) = {
    println( s"a = $a, b = $b")  }
fun31(5,6,7,8,9)         // 输出结果:WrappedArray(5, 6, 7, 8, 9)
fun32(5,6,7,8,9)         // 输出结果:a = 5, b = WrappedArray(6, 7, 8, 9)
// 4. 默认值参数
def fun4(name :String, age: Int) = {
    println( s"name = $name, age = $age")  }
fun4(age = 18, name = "scala")        // 输出结果:name = scala, age = 18

Scala中至简原则(了解即可)
1)return可以省略,scala会使用最后一行代码作为返回值
2)如果函数体只有一行代码,{}可以省略
3)返回值类型如果能够推断,那么定义方法时候,返回值类型可以省略
4)如果有return,返回值类型不能省略,必须指定
5)如果函数指定返回值类型unit,即使函数体中使用了return关键字也不能返回结果
6)scala如果期望无返回值类型,可以省略等号(为了兼容Java等语法,个人不推荐这么写)
7)如果无参函数/方法,申明函数/方法时加了(),调用时,()可写可不写
– def fun() = {…} , 调用时:fun 或者 fun()
8)如果无参函数/方法,申明函数/方法时没加(),调用时,()不能写
9)如果不关心名称,那么函数名 和 def都可以省略【就是匿名函数】
– (a:Int, b:Int) => { a + b }

四.匿名函数/匿名方法 与 函数之间的关系

  • 如果想给匿名函数/匿名方法加上名称,就出现函数的两种定义
(a:Int,b:Int) =>{
    a + b}   // 这是一个匿名方法
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值