问题描述
我有一些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),"left"
) //more code...
AFAIKT,这应该可以正常工作。但是,最终发生的是IntelliJ立即变灰import sqlContext.implicits._
,并且方法===
停止使用value === is not a member of org.apache.spark.sql.Dataset
进行解析。
因此由于某种原因,import sqlContext.implicits._
在传递函数参数时不起作用。我的问题是:
- 为什么隐式导入会停止工作?
- 我该怎么做才能使导入工作并且仍然使用函数参数?
解决方法
大多数情况不是在隐式中而是在类型不匹配中(隐式对类型非常敏感)。
抽象类Unit
的{{1}},a(Unit)
is the companion object中的 b(Unit)
。它没有类型Unit
(它具有类型Unit
)。 Unit.type
的类型为()
。
Unit
,a(Unit)
编译是因为在Scala中,任何类型(例如b(Unit)
)都可以转换为Unit.type
。
此外,您无法编写Unit
,a("prop_a1")
,因为b("prob_b1")
,a
是b
中的函数,您不能将它们应用于{{ 1}}。
所以虽然
Unit
编译(类似偶数
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],b) =>
a(1).joinWith(b("A"),a(true)("prop_a1") === b(???)("prob_b1"),"left"
) //more code...
有点奇怪,通常返回val join: (Unit => Dataset[MyCaseClassA],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...
是无参数函数的类型。
或者您可以使用by-name个参数编写
() => ...