Scala 2.13如何添加隐式参数且不破坏二进制兼容性
为Scala方法添加隐式参数并保证二进制兼容性的解决方案
核心思路
要同时满足二进制兼容、无公开API歧义、不保留旧方法作为公开API三个要求,关键是:保留原方法的字节码供旧二进制调用,但将其从公开API中隐藏,同时提供带隐式参数的新公开方法。
具体实现代码
import scala.annotation.deprecated class Foo { // 原方法:标记为过时+包私有,仅保留字节码用于二进制兼容 @deprecated("请使用带隐式参数的func方法", "1.0") private[yourpackage] def func(a: A, b: B): R = func(a, b)(defaultC) // 新的公开方法,带隐式参数 def func(a: A, b: B)(implicit c: C): R = { // 这里写方法的实际业务逻辑 // 示例:doSomething(a, b, c) } } // 定义默认的C实例,仅内部使用 private[yourpackage] val defaultC: C = new C(/* 默认参数 */)
方案解释
- 二进制兼容性:原方法的字节码仍然存在,MiMa工具检测时会识别到对应方法,不会抛出缺失错误,旧的二进制调用方可以正常运行。
- 无公开API歧义:原方法被标记为
private[yourpackage](包私有),不会出现在公开API文档中,用户只能看到新的带隐式参数的方法,调用时不会出现重载歧义。 - 不保留旧方法作为公开API:通过
@deprecated标记原方法过时,加上包私有修饰,外部无法直接调用,也不会被当作正式API使用。
补充说明
- 如果不需要包内访问,也可以用
private修饰原方法,Scala的private方法仍会生成字节码,不会被编译器优化掉,能满足MiMa的检测要求。 - 默认的
defaultC需要根据实际业务场景定义,保证原方法调用新方法时逻辑和旧版本一致。
内容的提问来源于stack exchange,提问作者Jack Koenig
相关产品推荐
相关产品推荐

