scala - 我如何以一种面向未来的方式使用 Scala “拉动我的库”?
问题描述
我使用 Scala 隐式类来扩展我经常使用的对象。例如,我有一个类似于 Spark 上定义的方法DataFrame
:
implicit class DataFrameExtensions(df: DataFrame) {
def deduplicate: Boolean =
df.groupBy(df.columns.map(col): _*).count
}
但是如果类已经定义了相同的方法,则不会调用隐式定义。如果我稍后升级到定义DataFrame#deduplicate
方法的新版本 Spark 会发生什么?客户端代码将默默地切换到新的实现,这可能会导致细微的错误(或明显的错误,问题较少)。
使用反射,如果在我的隐式定义之前已经定义,我可以抛出运行时错误。然后,理论上,如果我的隐式方法与现有方法冲突,我可以检测到它并重命名我的隐式版本。但是,一旦我升级 Spark、运行应用程序并检测到问题,使用 IDE 重命名旧方法为时已晚,因为现在对本机 Spark 版本的任何引用。我必须恢复我的 Spark 版本,通过 IDE 重命名方法,然后再次升级。不是世界末日,但不是一个伟大的工作流程。DataFrame
deduplicate
df.deduplicate
有没有更好的方法来处理这种情况?如何安全地使用“pimp my library”模式?
解决方案
您可以添加一个测试,以确保某些代码片段不会编译到DataFrameExtension
. 也许是这样的:
"(???: DataFrame).deduplicate" shouldNot compile
如果它在没有你的隐式转换的情况下编译,则意味着该方法deduplicate
已被 Spark 库引入。在这种情况下,测试失败,并且您知道您必须更新您的隐式。
推荐阅读
- iis - 如何在 IIS 中的目录浏览中更改或隐藏服务器名称
- query-string - 您可以将预定义的值从静态查询字符串传递到表单文本字段吗
- asp.net-core - 甚至使用 AsNoTracking() 进行跟踪
- python - ImportError:动态模块未定义模块导出函数(PyInit_sqlite3)
- javascript - 如何在不使用 JSON.parse 的情况下将数组的字符串数组转换为普通数组
- algorithm - KMP的LPS计算时间复杂度
- vb.net - 如何获取数据网格中所有列的值?
- django - 'pip' 不被识别为内部或外部命令、可运行程序或 docker web 应用程序上的批处理文件
- r - 如何用分组变量的平均值替换列中的一部分 NA?
- web-scraping - 通过 JS 引擎下载 HTML 源代码的最快方法是什么?