在Scala/Spark中使用来自一个模块的隐式值
我试图从另一个模块中的一个模块获取在Scala/Spark中使用来自一个模块的隐式值,scala,apache-spark,sbt,Scala,Apache Spark,Sbt,我试图从另一个模块中的一个模块获取SQLContext实例。第一个模块将其实例化为隐式sqlContext,我(错误地)认为可以在第二个模块中使用隐式参数,但编译器通知我: could not find implicit value for parameter sqlCtxt: org.apache.spark.sql.SQLContext 以下是我的骨架设置(我省略了导入和详细信息): 由于它是一个多项目sbt设置,我不想将实例env传递给所有相关对象,因为util中的内容实际上是一个共享库
SQLContext
实例。第一个模块将其实例化为隐式sqlContext
,我(错误地)认为可以在第二个模块中使用隐式参数,但编译器通知我:
could not find implicit value for parameter sqlCtxt: org.apache.spark.sql.SQLContext
以下是我的骨架设置(我省略了导入和详细信息):
由于它是一个多项目sbt设置,我不想将实例env
传递给所有相关对象,因为util
中的内容实际上是一个共享库。每个子项目(即应用程序)都有自己在main
方法中创建的实例
因为myFun
只是从隐式类DFExt
调用的,所以我考虑在每次调用之前创建一个隐式函数,即laimplicit val sqlCtxt=df.sqlContext
,它可以编译,但它有点难看,我不再需要SparkEnvironment
中的隐式函数
隐式sqlContext
实例不在范围内,因此编译失败。我不确定包对象是否可以工作,因为隐式值和参数在不同的包中
我想达到的目标可能实现吗?有更好的选择吗
我们的想法是让多个子项目使用相同的库和核心功能来共享同一个项目。它们通常一起更新,所以最好将它们放在一个地方。大多数库函数直接在Spark中的数据帧和其他结构上工作,但有时我需要执行一些需要SparkContext
或SQLContext
实例的操作,例如使用SQLContext.sql
编写查询,因为某些语法本机还不受支持(例如,用外部侧视图展平)
每个子项目都有自己的主方法来创建隐式实例。显然,库并不“知道”这一点,因为它们在不同的包中,我不会传递实例。我认为隐式是在运行时查找的,因此当应用程序运行时,会有一个定义为im的SQLContext实例有可能a)它不在范围内,因为它在不同的包中,或者b)我试图做的只是一个坏主意
目前只有一种主要方法,因为我首先必须将应用程序拆分为多个组件,而我还没有这样做
以防万一:
- Spark 1.4.1
- Scala 2.10
- sbt 0.13.8
myFun
放入DFExt
:
implicit final class DFExt(val df: DataFrame) extends AnyVal {
private implicit def sqlCtxt: SqlContext = df.sqlContext
// no need to take an implicit parameter, as sqlCtxt is already in scope
private def myFun(...) = ...
// The extension methods can now use sqlCtxt and/or myFun freely
}
您也可以将sqlCtxt
aval
,但是:1)DFExt
不能再扩展AnyVal
;2) 即使您调用的扩展方法不需要它,也需要初始化它;3) 对sqlCtxt
的任何调用都可能是内联的,因此您只需从df
访问val
,而不是此
。如果他们没有,这意味着你用的太少了
因为myFun只从隐式类DFExt调用,所以我考虑在每次调用之前创建一个隐式,即隐式val sqlCtxt=df.sqlContext,它可以编译,但它有点难看,我不再需要SparkEnvironment中的隐式
只需将隐式和myFun
放入DFExt
:
implicit final class DFExt(val df: DataFrame) extends AnyVal {
private implicit def sqlCtxt: SqlContext = df.sqlContext
// no need to take an implicit parameter, as sqlCtxt is already in scope
private def myFun(...) = ...
// The extension methods can now use sqlCtxt and/or myFun freely
}
您也可以将
sqlCtxt
aval
,但是:1)DFExt
不能再扩展AnyVal
;2) 即使您调用的扩展方法不需要它,也需要初始化它;3) 对sqlCtxt
的任何调用都可能是内联的,因此您只需从df
访问val
,而不是此
。如果没有,这意味着您使用它的次数太少而无关紧要。您可以尝试import env.\u
。祝您好运在Scala中制定出隐式查找规则-这些规则太疯狂了。如何导入在不同主方法中可能具有不同名称的实例?这怎么可能呢?这在符号表中是如何表示的呢?你能更新你的帖子吗?我不是指你上面所说的,而是从高层角度来说,你的设计有什么意义。你可以尝试import env.\u
。祝你好运在Scala中制定出隐式查找规则-这些规则太疯狂了。我如何导入一个可能在不同的主方法中具有不同名称的实例?这怎么可能呢?这在符号表中是如何表示的呢?你能更新你的帖子吗?我不是指你上面所说的,而是从高层次的角度来说,你的设计有什么意义。只是好奇,为什么要将它定义为def
?我本来想在答案中包含这一点,但认为它不够有用。补充。只是好奇,为什么要把它定义为一个def
?我本来想把它包括在答案中,但觉得它不够有用。补充。