前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >2021年大数据常用语言Scala(三十七):scala高级用法 高阶函数用法

2021年大数据常用语言Scala(三十七):scala高级用法 高阶函数用法

作者头像
Lansonli
发布2021-10-11 15:31:45
4870
发布2021-10-11 15:31:45
举报
文章被收录于专栏:Lansonli技术博客Lansonli技术博客

高阶函数用法

Scala 混合了面向对象和函数式的特性,在函数式编程语言中,函数是“头等公民”,它和Int、String、Class等其他类型处于同等的地位,可以像其他任何数据类型一样被传递和操作。

高阶函数包含:作为值的函数、匿名函数、闭包、柯里化等等。

作为值的函数

在scala中,函数就像和数字、字符串一样,可以将函数传递给一个方法。我们可以对算法进行封装,然后将具体的动作传递给算法,这种特性很有用。

我们之前学习过List的map方法,它就可以接收一个函数,完成List的转换。

示例:将一个小数列表中的每个元素转换为对应个数的小星星

List(1, 2, 3...) => *, \, \

代码:

代码语言:javascript
复制
val list = List(1, 2, 3, 4)

// 字符串*方法,表示生成指定数量的字符串
val func_num2star = (num:Int) => "*" * num

print(list.map(func_num2star))

匿名函数

上面的代码,给(num:Int) => "*" * num函数赋值给了一个变量,但是这种写法有一些啰嗦。在scala中,可以不需要给函数赋值给变量,没有赋值给变量的函数就是匿名函数

示例:优化上述代码

代码语言:javascript
复制
val list = List(1, 2, 3, 4)

list.map(num => "*" * num).foreach(println)
// 因为此处num变量只使用了一次,而且只是进行简单的计算,所以可以省略参数列表,使用_替代参数
list.map("*" * _).foreach(println)

柯里化(多参数列表)

list.fold(100)(_ + _)

柯里化(Currying)允许方法接收多个参数列表的语法特性。

多数用于隐式转换或者在逻辑上划分不同批次的参数用。

特点:参数如果不传递完全,得到一个函数

柯里化过程解析

使用柯里化,让传递匿名函数作为参数的语法更为简洁

示例:编写一个泛型方法,用来完成两个值类型的计算(具体的计算封装到函数中)

代码语言:javascript
复制
object CurryingDemo2 {

  // 实现对两个数进行计算的方法
  def calc[A <: AnyVal](x:A, y:A, func_calc:(A, A)=>A) = {
    func_calc(x, y)
  }

  // 柯里化:实现对两个数进行计算
  def calc_carried[A <: AnyVal](x:A, y:A)(func_calc:(A, A)=>A) = {
    func_calc(x, y)
  }

  def main(args: Array[String]): Unit = {
    // 这种写法是不能被简化的,必须要写出函数的定义
    println(calc(10, 10, (x:Int, y:Int)=> x + y))
    println(calc(10.1, 10.2, (x:Double, y:Double)=> x*y))
    
    // 柯里化之后可以快乐地使用下划线了
    println(calc_carried(10, 10)(_ + _))
    println(calc_carried(10.1, 10.2)(_ * _))
    println(calc_carried(100.2, 10)(_ - _))
  }
}

闭包

闭包其实就是一个函数,只不过这个函数的返回值依赖于声明在函数外部的变量。

可以简单认为,就是可以访问不在当前作用域范围的一个函数。

可以不修改方法体,通过外部变量来控制方法返回结果

示例:定义一个闭包

代码语言:javascript
复制
object ClosureDemo {

  def add(x:Int) = {
    val y = 10

    // add返回一个函数,该函数引用了add方法的一个局部变量
    val funcAdd = () => x + y
    funcAdd
  }

  def main(args: Array[String]): Unit = {

    // 调用add方法时,任然可以引用到y的值
    // funcAdd函数就是一个闭包
    println(add(10)())
  }
}

上面的演示只是使用一个普通的int值来做的闭包。 如果依赖的外部变量是一个函数呢?

那就是,无需修改方法体, 修改外部函数就能修改计算逻辑。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-05-14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 高阶函数用法
    • 作为值的函数
      • 匿名函数
        • 柯里化(多参数列表)
          • 闭包
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档