scala中的函数式编程

scala中的函数式编程

首先要理解什么是纯函数:

在函数的调用过程中,没有任何的全局状态被修改。

举个不那么恰当的例子:

object functionalPrograming {
   // 定义一个全局变量
  var list: List[Double] = Nil
    
  // 主方法中分别调用两种类型的函数
  def main(args: Array[String]): Unit = {
    println(sin(1.0))
    println(list)
    println("----------")
    println(sinList(1.0))
    println(list)
  }

  // 定义一个纯函数
  def sin(x: Double): Double = {
    scala.math.sin(x)
  }
  // 定义一个非纯函数
  def sinList(x: Double): Double = {
    list = list :+ scala.math.sin(x)
    scala.math.sin(x)
  }
}

===> 0.8414709848078965
===> List()
===> ----------
===> 0.8414709848078965
===> List(0.8414709848078965)

可以看到,同样实现返回 sin(x) 功能的函数,代码中定义的 sin 方法没有任何的全局状态被修改;而定义的 sinList 方法中,每次调用都向全局变量 list 中添加一次计算结果。

在实际的开发过程中,纯函数极大的简化了函数的分析、测试和调试。我们可以不用考虑该函数的上下文信息。

而且由于没有任何全局的对象被修改,对函数的并发调用也是安全可靠的,不需要任何线程安全的编写技巧。多线程程序的大部分

考虑另外一种情况:

object functionalPrograming02 {
    // 主方法
  def main(args: Array[String]): Unit = {
      // 定义一个变量,作为 sinAnd 函数的因子
    var factor: Int = 2
      // 定义 sinAnd 函数
    val sinAnd: Double => Double = (x: Double) => scala.math.sin(x) * factor
      
    println(sinAnd(1))
    println("-----------------")
    factor = 3
    println(sinAnd(1))
  }
}

===> 1.682941969615793
===> -----------------
===> 2.5244129544236893

可以看到,尽管 sinAnd 是一个不可变的函数字面量,当 factor 改变时,sinAnd 的行为也跟着改变。

然而 factor 并不是 sinAnd 的参数,而是一个自由变量,是一个当前作用域中某个值的引用。所以编译器创建了一个闭包,用于包含 sinAnd 与它引用的外部变量的上下文信息,从而也就绑定了外部变量本身。
一般来说 sinAnd 也叫纯函数。

请注意区别调用函数引发外部变量改变,和改变外部变量影响函数结果的差异。

ps:

我们可以将后者写成方法

object SinAnd {
    var factor = 2
    def sinAnd(x: Int) = scala.math.sin(X) * factor
}

SinAnd.sinAnd(1)
===> 1.682941969615793
SinAnd.factor = 3
SinAnd.sinAnd(1)
===> 2.5244129544236893

未完

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值