Spark 隐含不在范围内解析

Spark implicits not resolving inside of scope

我有一些 scala/spark 代码如下所示:

  import sqlContext.implicits._

  val join: (Dataset[MyCaseClassA], Dataset[MyCaseClassB]) => Dataset[AB] = (a, b) =>
    a.joinWith(b,
      a("prop_a1") === b("prob_b1"),
      "left"
    ) //more code...

这工作正常,编译和一切。但是假设我想做一些函数式编程,所以我将整个事情重构为:

  import sqlContext.implicits._

  val join: (Unit => Dataset[MyCaseClassA], Unit => Dataset[MyCaseClassB]) => Dataset[AB] = (a, b) =>
     a(Unit).joinWith(b(Unit),
        a("prop_a1") === b("prob_b1"),
        "left"
     ) //more code...

据我所知,这应该可以正常工作。然而,最终发生的是 IntelliJ 立即变灰 import sqlContext.implicits._,方法 === 停止解析为 value === is not a member of org.apache.spark.sql.Dataset

因此,出于某种原因,import sqlContext.implicits._ 在传递函数参数时不起作用。我的问题是:

  1. 为什么隐式导入停止工作?
  2. 我怎样做才能使导入工作并仍然使用函数参数?

主要不是隐式而是类型不匹配(隐式对类型非常敏感)。

Unit a(Unit)b(Unit) is the companion object 摘要 class Unit。它没有类型 Unit(它有类型 Unit.type)。 () 的类型为 Unit.

a(Unit)b(Unit) 编译只是因为在 Scala 中任何类型(例如 Unit.type)都可以转换为 Unit.

你也不能写a("prop_a1")b("prob_b1")因为abUnit的函数,你不能将它们应用到String.

所以虽然

val join: (Unit => Dataset[MyCaseClassA], Unit => Dataset[MyCaseClassB]) => Dataset[AB] = (a, b) =>
  a(Unit).joinWith(b(Unit),
    a(Unit)("prop_a1") === b(Unit)("prob_b1"),
    "left"
  ) //more code...

编译(同样甚至

val join: (Unit => Dataset[MyCaseClassA], Unit => Dataset[MyCaseClassB]) => Dataset[AB] = (a, b) =>
  a(1).joinWith(b("A"),
    a(true)("prop_a1") === b(???)("prob_b1"),
    "left"
  ) //more code...

会编译)看来你的意思是

val join: (Unit => Dataset[MyCaseClassA], Unit => Dataset[MyCaseClassB]) => Dataset[AB] = (a, b) =>
  a(()).joinWith(b(()),
    a(())("prop_a1") === b(())("prob_b1"),
    "left"
  ) //more code...

另外接受Unit有点奇怪,通常返回Unit

你可以写

val join: (() => Dataset[MyCaseClassA], () => Dataset[MyCaseClassB]) => Dataset[AB] = (a, b) =>
  a().joinWith(b(),
    a()("prop_a1") === b()("prob_b1"),
    "left"
  ) //more code...

这里 () => ... 又名 Function0[...] 是 no-argument 函数的类型。

或者你可以写 by-name 个参数

val join: (=> Dataset[MyCaseClassA], => Dataset[MyCaseClassB]) => Dataset[AB] = (a, b) =>
  a.joinWith(b,
    a("prop_a1") === b("prob_b1"),
    "left"
  ) //more code...