Scala柯里化

1 什么是柯里化

柯里化(Currying)指的是把原来接受多个参数的函数变换成接受一个参数的函数过程,并且返回接受余下的参数且返回结果为一个新函数的技术。

2 例子

(1)一个普通的非柯里化的函数定义,实现一个加法函数:

scala> def plainOldSum(x:Int,y:Int)=x+y
plainOldSum: (x: Int, y: Int)Int

scala> plainOldSum(1,2)
res0: Int = 3

(2)使用“柯里化”技术来定义这个加法函数,原来函数使用一个参数列表,“柯里化”把函数定义为多个参数列表:

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调用这个函数类型的值。

(3)使用下面两个分开的定义在模拟curriedSum柯里化函数:

//首先定义第一个函数:
scala> def first(x:Int)=(y:Int)=>x+y
first: (x: Int)Int => Int

//然后我们使用参数1调用这个函数来生成第二个函数:
scala> val second =first(1)
second: Int => Int = <function1>
scala> second(2)
res2: Int = 3

(4)使用curriedSum 来定义second

scala> val onePlus=curriedSum(1)_
onePlus: Int => Int = <function1>

//下划线“_” 作为第二参数列表的占位符, 这个定义的返回值为一个函数,当调用时会给调用的参数加一。

scala> onePlus(2)
res3: Int = 3
//调用生成的函数,给函数传入参数,即可得到我们想要的结果。

3 总结

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

4 案例

例如 设计一个获取本地文本文件的所有行数据的功能,主函数功能主要是创建文件流读取文件的所有行,在读取过程中,需要做很多的辅助操作如判断本地文件是否存在和可读和关闭文件流。使用scala的函数式柯里化代码看上去将变得非常优雅

def getLines(filename:String):List[String]={
    getLines(filename)(isReadable)(closeStream)
}
def getLines(filename: String)(isFileReadable: (File) => Boolean)(closableStream: (Closeable) => Unit):List[String] = {
  val file = new File(filename)
  if (isFileReadable(file)) {
    val readerStream = new FileReader(file)
    val buffer = new BufferedReader(readerStream)
    try {
      var list: List[String] = List()
      var str = ""
      var isReadOver = false
      while (!isReadOver) {
        str = buffer.readLine()
        if (str == null) isReadOver = true
        else list = str :: list
      }
      list.reverse
    } finally {
      closableStream(buffer)
      closableStream(readerStream)
    }
  } else {
    List()
  }
}

def isReadable(file: File) = {
  if (null != file && file.exists() && file.canRead()) true
  else false
}
def closeStream(stream: Closeable) {
  if (null != stream) {
    try {
      stream.close
    } catch {
      case ex => Log.error(“[”+this.getClass.getName+”.closeStream]”,ex.getMessage)
    }
  }
}

使用柯里化特性可以将复杂逻辑简单化,并能将很多常漏掉的主函数业务逻辑之外的处理暴露在函数的定义阶段,提高代码的健壮性,使函数功能更加细腻化和流程化。

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值