Scala Currying和自动类型依赖的封闭构造

时间:2020-02-23 14:41:46  来源:igfitidea点击:

Scala Currying是将包含多个参数的函数转换为单个参数的过程。

考虑一个将两个数字相乘的示例。
打开scala REPL shell并创建乘法方法为

def multiply(a:Int,b:Int) = a*b
Output:multiply: (a: Int, b: Int)Int

乘法函数接受Integer数据类型的两个参数a和b并返回a * b的结果,该结果是Integer数据类型。

将该方法作为乘法(4,5)调用,您将得到输出为res10:Int = 20

现在让我们将此函数应用为currying;

def multiply(a:Int) = (b:Int) => a*b

输出:乘以:(a:Int)Int => Int

乘法函数在函数声明中采用Integer数据类型的单个参数a。
在函数内部,它需要再加上一个Integer数据类型的参数b并返回a * b作为结果。

假设如果我们使用单个参数调用函数,则函数闭包引用返回为

multiply(5)
res10: Int => Int = <function1>

通过传递两个参数来调用该函数

multiply(4)(5)
res11:Int = 20

自动类型依赖的封闭构造

在scala中,无参数函数名称允许作为方法的参数。
调用此类方法时,将评估无效函数,而不评估无参数函数名称的实际参数。
无效函数封装了相应参数的计算,称为"按名字求值"。

让我们看一个例子,以更清楚地了解这一点。

TypeDependent.scala

package com.theitroad.scala

object TypeDependent {
def main(args: Array[String]) {
  def forloop(rule: => Boolean)(body: => Unit): Unit =
    if (rule) {
      body
      forloop(rule)(body)
    }
  var i = 7
  forloop(i > 2) {
    println("i: " + i)
    i -= 1
  }
}
}

我们正在创建一个对象TypeDependent,它定义了一个方法" forloop"。
该方法采用规则和正文两个参数。
每当在forloop主体中使用形式参数时,都会评估隐式创建的null函数。
这里我们实现了for循环,下图显示了上面程序的输出。

现在让我们看一下具有更多操作的更复杂的示例。

Typedep.scala

package com.theitroad.scala

object Typedep extends App {

def t1(body: => Unit): Criteria =
  new Criteria(body)
protected class Criteria(body: => Unit) {
  def condition(rule: => Boolean) {
    body
    if (!rule) condition(rule)
  }
}
var x = 7
t1 {
  println("x: " + x)
  x -= 1
} condition (x == 2)
}

我们正在创建一个scala对象,其中包含方法t1,该方法接受Unit数据类型的body参数并返回Criteria类的实例。
标准类定义了一种方法" condition",该方法在递减x的值后,如果x == 2,则检查条件。