我开始在代码库中添加一些隐式转换。我并没有真正研究它在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代码,我发现包含隐式的“标准”方法是在对象中定义它们并将其导入
import com.package.implicits._
或类似的东西。
是否有任何理由将我的代码转换为这种方式工作?是否有任何理由不在Scala特征中包含隐式转换?
答案 0 :(得分:2)
从功能的角度来看,没有区别-隐式的行为将相同。
那为什么要对自己施加额外的限制?从模块导入隐式通常比扩展特征更干净。如果您不想在大量上下文中泛滥,您可以import com.package.implicits.DataFrameTest
。对于扩展类和隐式转换,我通常有单独的隐式对象。
特性通常用作某些功能的类型边界或封装。
顺便说一句,隐式另一个常见的地方是伴随对象。然后它会自动与您的案例类一起导入。