Scala 深入理解高阶函数

Scala 深入理解高阶函数

1. 概念

Scala 混合了面向对象和函数式的特性,我们通常将可以作为参数传递到方法中的表达式叫做函数。在函数式编程语言中,函数是“头等公民”,高阶函数包含:作为值的函数、匿名函数、闭包、柯里化等等。

2. 作为值的函数

可以像任何其他数据类型一样被传递和操作的函数,每当你想要给算法传入具体动作时这个特性就会变得非常有用。
Scala 深入理解高阶函数_第1张图片
定义函数时格式:val 变量名 = (输入参数类型和个数) => 函数实现和返回值类型
“=”表示将函数赋给一个变量
“=>”左面表示输入参数名称、类型和个数,右边表示函数的实现和返回值类型

3. 匿名函数

在 Scala 中,你不需要给每一个函数命名,没有将函数赋给变量的函数叫做匿名函数。
Scala 深入理解高阶函数_第2张图片
由于 Scala 可以自动推断出参数的类型,所有可以写的跟精简一些
这里写图片描述
还记得神奇的下划线吗?这才是终极方式
这里写图片描述

4. 柯里化

4.1 什么是柯里化

柯里化(Currying)指的是把原来接受多个参数的函数变换成接受一个参数的函数过程,并且返回接受余下的参数且返回结果为一个新函数的技术。
Scala 深入理解高阶函数_第3张图片

4.2 案例

  • 一个普通的非柯里化的函数定义,实现一个加法函数:
scala> def plainOldSum(x:Int,y:Int)=x+y
plainOldSum: (x: Int, y: Int)Int
scala> plainOldSum(1,2)
res0: Int = 3
  • 使用“柯里化”技术来定义这个加法函数,原来函数使用一个参数列表,“柯里化”,把函数定义为多个参数列表:
scala> def curriedSum(x:Int)(y:Int)=x+y
curriedSum: (x: Int)(y: Int)Int
scala> curriedSum(1)(2)
res1: Int = 3
当你调用 curriedSum (1)(2)时,实际上是依次调用两个普通函数(非柯里化函数),
第一次调用使用一个参数 x,返回一个函数类型的值,
第二次使用参数 y 调用这个函数类型的值。
  • 使用下面两个分开的定义在模拟 curriedSum 柯里化函数:
首先定义第一个函数:
scala> def first(x:Int)=(y:Int)=>x+y
first: (x: Int)Int => Int
然后我们使用参数 1 调用这个函数来生成第二个函数:
scala> val second =first(1)
second: Int => Int = 
scala> second(2)
res2: Int = 3
  • 使用 curriedSum 来定义 second
scala> val onePlus=curriedSum(1)_
onePlus: Int => Int = 
下划线“_” 作为第二参数列表的占位符, 这个定义的返回值为一个函数,当调用时会给
调用的参数加一。
scala> onePlus(2)
res3: Int = 3
调用生成的函数,给函数传入参数,即可得到我们想要的结果。

4.3 总结

scala 柯里化风格的使用可以简化主函数的复杂度,提高主函数的自闭性,提高功能上的可扩张性、灵活性。可以编写出更加抽象,功能化和高效的函数式代码。

5. 闭包

闭包是一个函数,返回值依赖于声明在函数外部的一个或多个变量。
闭包通常来讲可以简单的认为是可以访问不在当前作用域范围内的一个函数。

案例

package cn.cheng.closure
/**
* scala 中的闭包
* 闭包是一个函数,返回值依赖于声明在函数外部的一个或多个变量。
*/
object ClosureDemo {
    def main(args: Array[String]): Unit = {
    val y=10
    //变量 y 不处于其有效作用域时,函数还能够对变量进行访问
    val add=(x:Int)=>{
        x+y
    }
    //在 add 中有两个变量:x 和 y。其中的一个 x 是函数的形式参数,
    //在 add 方法被调用时,x 被赋予一个新的值。
    // 然而,y 不是形式参数,而是自由变量
    println (add(5)) // 结果 15
    }
}

喜欢就点赞评论+关注吧

Scala 深入理解高阶函数_第4张图片

感谢阅读,希望能帮助到大家,谢谢大家的支持!

你可能感兴趣的:(scala)