Scala | Spark |调用未定义的方法

Scala | Spark |调用未定义的方法,scala,azure,apache-spark,Scala,Azure,Apache Spark,我是Scala新手,试图掌握语言基础知识。我有使用Java API的Spark的工作知识 我很难理解一些scala代码,因此我无法用Java编写同样的代码。我得到了这段代码 据我所知,read方法返回一个类型为org.apache.spark.sql.DataFrameReader的对象,而这没有任何方法cosmosDB(),那么这段代码是如何工作的。另外,如何将此代码转换为Java 谢谢您看到的是Scala隐式转换的魔力。编译器发现您打算调用DataFrameReader的cosmosDB方法

我是Scala新手,试图掌握语言基础知识。我有使用Java API的Spark的工作知识

我很难理解一些scala代码,因此我无法用Java编写同样的代码。我得到了这段代码

据我所知,read方法返回一个类型为
org.apache.spark.sql.DataFrameReader
的对象,而这没有任何方法
cosmosDB()
,那么这段代码是如何工作的。另外,如何将此代码转换为Java


谢谢

您看到的是Scala隐式转换的魔力。编译器发现您打算调用
DataFrameReader
cosmosDB
方法,并且正如您所注意到的,没有具有正确签名的方法

当你

import com.microsoft.azure.cosmosdb.spark.schema._
您还导入了的内容(截至本文撰写时的当前git提交,最后一次更新是在2017年,因此它是稳定的代码)。导入的相关位是

implicit def toDataFrameReaderFunctions(dfr: DataFrameReader): DataFrameReaderFunctions
接受一个参数的
隐式def
向编译器发出信号,如果此
def
在范围内,编译器可以在以下情况插入对此方法的调用:

  • 它有一个
    DataFrameReader
  • 正在调用的方法不是
    DataFrameReader
  • com.microsoft.azure.cosmosdb.spark.schema.DataFrameReaderFunctions
    具有所需名称和签名的成员
由于
DataFrameReaderFunctions
有一个方法
cosmosDB
,编译器随后将代码翻译为

toDataFrameReaderFunctions(spark.read).cosmosDB(readConfig)

使用隐式转换使其看起来像是在向类型添加方法而不修改类型的一般方法称为扩展方法或扩展方法。通常应该避免隐式转换:它们通常会使代码难以理解,范围内错误的隐式转换可能会使您不打算编译的代码。对于这样的扩展,有一种替代方法:使用
隐式类
,其中编译器基本上自动生成隐式转换,但这不允许使用
Int
代替
字符串

,非常感谢@Levi。如果你能帮助我理解如何将这些代码翻译成Java。另外,如果您指导我阅读任何可以深入学习Scala的材料或在线课程。因此,对于Java翻译,很大程度上取决于特定名称的损坏(例如
com.microsoft.azure.cosmosdb.spark.schema
(可能类似于
com.microsoft.azure.cosmosdb.spark.schema.$package
,请尝试使用IDE浏览)。由于它是Scala对象,
toDataFrameReaderFunctions
应该是
静态的
。至于复制
配置
,这需要对Scala代码进行一些研究。假设它是一个case类(即在github上该模块的Scala代码中,它是
case类配置
),然后通过调用
com.microsoft.azure.cosmosdb.spark.Config.Config$来构造
Config
。使用Scala
Map
应用
。从Java
Map
获取Scala
Map
的最佳方法可能是研究类似
Scala.collection.JavaConversions$.mapascalamap
的方法将为您提供一个可变的
映射
,而此API几乎肯定需要一个不可变的
映射
toMap
将在这方面有所帮助。
toDataFrameReaderFunctions(spark.read).cosmosDB(readConfig)