这个问题在这里已有答案:
我开始在我的代码库中添加一些隐式转换。我没有真正研究如何在Scala中完成这些工作或查看许多示例,因此我将这些实现为特征。例如,此代码段允许您测试Spark DataFrame的架构:
trait DataFrameImplicits {
implicit class DataFrameTest(df: DataFrame) {
def testInputFields(requiredCols: Map[String, DataType]): Unit = {
requiredCols.foreach { case (colName: String, colType: DataType) =>
if (!df.schema.exists(_.name == colName) || df.schema(colName).dataType.simpleString != colType.simpleString)
throw exceptWithLog(DFINPUT_TEST_BADCOLS, s"Input DataFrame to Preprocess.process does not contain column $colName of type ${colType.simpleString}")
}
}
然后通过以下方式实现:
object MyFunctionality extends DataFrameImplicits {
def myfunc(df: DataFrame): DataFrame = {
df.testInputFields( ??? )
df.transform( ??? )
}
}
现在,最近查看更多Scala代码,我发现包含implicits的“标准”方法是在对象中定义它们并导入它们
import com.package.implicits._
或类似的东西。
是否有任何理由将我的代码转换为以这种方式工作?有没有理由不在Scala特征中包含隐式转换?
从功能的角度来看,没有区别 - implicits将以相同的方式运行。
那么为什么要对自己施加额外限制?从模块导入隐式通常比扩展特征更简洁。如果你不想用大量的暗示充斥你的背景,你可以只是import com.package.implicits.DataFrameTest
。我通常有扩展类和隐式转换的单独隐式对象。
特征通常用作某些功能的类型边界或封装。
顺便说一句,implicits的另一个常见位置是伴随对象。然后它会自动导入您的案例类。