Scala:未指定的值参数证据$3

标签 scala apache-spark

我环顾四周,发现了其他几个例子,但从这些答案中我并没有真正理解实际发生了什么。

我想了解为什么以下代码无法编译:

val df = readFiles(sqlContext).
    withColumn("timestamp", udf(UDFs.parseDate _)($"timestamp"))

给出错误:

Error:(29, 58) not enough arguments for method udf: (implicit evidence$2: reflect.runtime.universe.TypeTag[java.sql.Date], implicit evidence$3: reflect.runtime.universe.TypeTag[String])org.apache.spark.sql.UserDefinedFunction.
Unspecified value parameter evidence$3.
            withColumn("timestamp", udf(UDFs.parseDate _)($"timestamp")).
                                                         ^

而这段代码编译:

val parseDate = udf(UDFs.parseDate _)
val df = readFiles(sqlContext).
    withColumn("timestamp", parseDate($"timestamp"))

显然我找到了一个“解决方法”,但我真的很想了解:

  1. 这个错误的真正含义。我在 TypeTags 和 ClassTags 上找到的信息真的很难理解。我不是来自 Java 背景,这可能没有帮助,但我想我应该能够掌握它……
  2. 如果我可以在没有单独的函数定义的情况下实现我想要的

最佳答案

错误信息确实有点误导;原因是函数 udf 采用隐式参数列表,但您传递的是实际参数。由于我对 spark 了解不多,并且由于 udf 签名有点复杂,我将尝试用一个简化的示例来解释发生了什么。

实际上 udf 是一个给定一些显式参数的函数,而一个隐式参数列表给你另一个函数;让我们定义以下函数,给定一个 T 类型的 pivot,我们有一个隐含的 Ordering 将作为允许我们拆分的函数给出一分为二的序列,一个包含小于 pivot 的元素,另一个包含更大的元素:

def buildFn[T](pivot: T)(implicit ev: Ordering[T]): Seq[T] => (Seq[T], Seq[T]) = ???

让我们忽略实现,因为它并不重要。现在,如果我执行以下操作:

val elements: Seq[Int] = ???
val (small, big) = buildFn(10)(elements)

我会犯与您在代码中显示的相同类型的错误,即编译器会认为我将 elements 作为隐式参数列表显式传递,这将无法编译。我的示例的错误消息将与您的错误消息有所不同,因为在我的情况下,我错误地为隐式参数列表传递的参数数量与预期的匹配,然后错误将与类型不对齐。

相反,如果我把它写成:

val elements: Seq[Int] = ???
val fn = buildFn(10)
val (small, big) = fn(elements)

在这种情况下,编译器会正确地将隐式参数传递给函数。我不知道有什么方法可以规避这个问题,除非你想显式地传递实际的隐式参数,但我觉得它很丑陋而且并不总是实用的;供引用,这就是我的意思:

val elements: Seq[Int] = ???
val (small, big) = buildFn(10)(implicitly[Ordering[Int]])(elements)

关于Scala:未指定的值参数证据$3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34740501/

相关文章:

r - SparkR 与 sparklyr

apache-spark - 如何使用新的 Hadoop parquet magic commiter 通过 Spark 自定义 S3 服务器

Scala 参与者和共享状态

python - 如何在Spark中使用ElasticSearch在脚本文档中更新或部分更新?

java - Java/Scala 中可以禁用边界检查吗?

hadoop - 从 sbt 文件中的 spark 库中排除 hadoop 依赖

scala - 如何在多列上使用 spark quantilediscretizer

scala - Scala(单例)对象与典型的类级工件相比有什么好处

scala - 顶点属性继承 - Graphx Scala Spark

sql - 将从文本文件加载的列表传递到 Spark SQL 中的 SQL 查询