当前位置: 首页 > 知识库问答 >
问题:

这段scala代码是怎么回事?回调函数

凌远
2023-03-14
/**
  * Returns the number of rows in the [[Dataset]].
  * @group action
  * @since 1.6.0
  */
def count(): Long = withCallback("count", groupBy().count()) { df =>
  df.collect(needCallback = false).head.getLong(0)
}
/**
  * Wrap a Dataset action to track the QueryExecution and time cost, then report to the
  * user-registered callback functions.
  */
private def withCallback[U](name: String, df: DataFrame)(action: DataFrame => U) = {
  try {
      df.queryExecution.executedPlan.foreach { plan => plan.resetMetrics()
    }
    val start = System.nanoTime()
    val result = action(df)
    val end = System.nanoTime()
    sqlContext.listenerManager.onSuccess(name, df.queryExecution, end - start)
    result
  } catch {
  case e: Exception =>
    sqlContext.listenerManager.onFailure(name, df.queryExecution, e)
    throw e
  }
}

这是怎么回事?我不明白count()是如何既等于withCallback又有一个主体的;不知何故,它是在withCallback返回的dataframe上调用的,但我不明白语法。

共有1个答案

卞安邦
2023-03-14

count()方法实际上没有自己的主体。看起来像count()的正文实际上是一个函数文本,它定义了With Callback的“action”参数。严格地说,count()本身只是对方法With callback(name,df)(action)的调用。(在Scala中,方法可以有多个参数列表。)with callback的值是result,也就是action函数的计算结果。

然而,你正在经历的“困惑”是有意为之的。这个习惯用法--一个具有类型为函数或名值的结束参数列表的方法--允许人们定义在语法上看起来像语言扩展的东西。我们习惯于有特殊语法的语言,比如...

try {
  // your code here
}

在Scala中,您可以编写自己的函数,如...

// don't ask me why you would want to do this
def unreliably[T]( operation : =>T ) : Option[T] = {
   if (scala.math.random < 0.1) Some(operation) else None
}
unreliably {
  // your code here
}

它看起来就像新的语言语法!为了让它更像你的激励示例,我们可以修改定义,使其必须参数列表······

// don't ask me why you would want to do this
def unreliably[T]( probability : Double )( operation : =>T ) : Option[T] = {
   if (scala.math.random < probability) Some(operation) else None
}

现在,我们可以调用函数为...

unreliably( probability = 0.9 ) {
  // your code here
}

...你的代码有90%的机会被执行。代码定义了一个表达式,而不仅仅是一些无价值的语句,因此您还可以编写

val result = unreliably( probability = 0.9 ) {
   "great day"
}
println(s"""It's a ${result.getOrElse("terrible day")}.""")
 类似资料:
  • 问题内容: 为什么这种尝试创建咖喱函数列表的方法不起作用? 这里发生了什么? 实际上执行我期望上述功能执行的功能是: 问题答案: 在Python中,在循环和分支中创建的变量没有作用域。您创建的所有函数都引用了相同的变量,该变量在循环的最后一次迭代中设置为。 解决方案是创建一个返回函数的函数,从而确定迭代器变量的范围。这就是该方法行之有效的原因。例如:

  • 该怎么解决?之前都能启动的,也没有找到哪里写了这个路径的文件;打包也没报错 yml文件: 这里是读取这两个yaml文件的意思吗?

  • 问题内容: 我正在研究JDK 1.7的新功能,但我无法了解MethodHandle是为什么设计的?我了解静态方法的(直接)调用(以及在这种情况下简单的Core Reflection API的使用)。我也了解(直接)调用虚拟方法(非静态,非最终)(以及使用需要经过Class层次结构的Core Reflection API )。非虚拟方法的调用可以视为前一种的特殊情况。 是的,我知道重载存在问题。如果

  • update 动画开始播放后,每帧都会触发此回调。 Type Parameters Info Function animation 返回当前动画对象 var updates = 0; anime({ targets: '.update-demo .el', translateX: 270, delay: 1000, direction: 'alternate', loop:

  • 我为covered_by函数传入了两个SLDPoint的数组。 其中第一个数组中的点为: 第二个数组中的点为: 结果check_covered的值居然是true,也就是说第一个图形在第二个图形里面?? 图中有更直观的展示。整个这个大的矩形就是我输入的第1个数组所形成的封闭图形。而在它的上方有个非常非常小的矩形就是我输入的第2个数组所形成的封闭图形。这结果是不是不太对?我确定我没有弄反,其余几百个图