【问题标题】:How to deprecate a parameter with default value in Scala?如何在Scala中弃用具有默认值的参数?
【发布时间】:2018-11-25 09:48:51
【问题描述】:

在 metrics-scala 库中,我们有以下方法:

def timer(name: String, scope: String = null): Timer

我想弃用 scope 参数并将其从下一个主要版本中删除。

我试过了:

def timer(name: String): Timer
@deprecated(...)
def timer(name: String, scope: String): Timer

但这会导致当前主要版本中已经存在二进制向后兼容性问题(见下文 *)。

我也试过这个:

def timer(name: String, @deprecated(...) scope: String = null): Timer

但这会在timer 内部发出警告,而不是给timer 的调用者。

我是否遗漏了什么,或者真的不可能弃用具有默认值的参数?

(*) 选项 1 的 Mima 报告:

sbt:metrics4-scala-root> mimaReportBinaryIssues
[error]  * synthetic method timer$default$2()java.lang.String in class nl.grons.metrics4.scala.MetricBuilder does not have a correspondent in current version
[error]    filter with: ProblemFilters.exclude[DirectMissingMethodProblem]("nl.grons.metrics4.scala.MetricBuilder.timer$default$2")

【问题讨论】:

  • 第一个选项应该有效。你为什么说它会导致向后兼容性=
  • 因为美麻这么说。我更新了问题。
  • 一种蛮力的方法是添加一个已弃用的方法def timer$default$2(): String = null。虽然我认为奥列格的答案更好。

标签: scala


【解决方案1】:

我相信(但我现在没有 MiMa 设置来检查)您可以使用特征:

object Foo extends DeprecatedFoo {
  def timer(name: String): Unit = { println("called new shiny version") }
}

trait DeprecatedFoo {
  @deprecated("", "")
  def timer(name: String, scope: String = null) = { println("called bad old version")}
}

Foo.timer("xx") // calls new version
Foo.timer("xx", null) // calls old version and issues a warning:

为旧版本编译的代码将执行invokevirtual Foo/timer(Ljava/lang/String;Ljava/lang/String;)Z,这也将解析为旧版本。

【讨论】:

    猜你喜欢
    • 2017-06-20
    • 2013-09-21
    • 1970-01-01
    • 2011-04-08
    • 2014-02-27
    • 1970-01-01
    • 1970-01-01
    • 2016-10-30
    • 2014-01-23
    相关资源
    最近更新 更多