1

我想出了如何使用 aTypeTag将空参数列表添加到现有方法并绕过擦除错误。我想了解我的 hack 是如何工作的,以及是否有更好的方法来实现预期的结果。

我有以下happyStuff方法:

object Happy {

  def happyStuff(s: String): String = {
    "happy " + s
  }

}

我想更改方法签名happyStuff并弃用旧方法,如下所示。

object Happy {

  @deprecated("this is the old one")
  def happyStuff(s: String): String = {
    "happy " + s
  }

  def happyStuff()(s: String): String = {
    "happy " + s
  }

}

此代码给出以下错误消息:“def happyStuff(s: String): String at line 6 and def happyStuff()(s: String): String at line 10 have the same type after erasure”。

这个 hack 让我得到了我想要的结果:

object Happy {

  @deprecated("this is the old one")
  def happyStuff(s: String): String = {
    "happy " + s
  }

  def happyStuff[T: TypeTag](x: T)(s: String): String = {
    "happy " + s
  }

}

如何TypeTag解决擦除消息?有没有更好的方法来达到预期的结果?

4

1 回答 1

3

这不是类型标记,而是您放在那里的附加参数:

object Happy {

  @deprecated("this is the old one")
  def happyStuff(s: String): String = {
    "happy " + s
  }

  def happyStuff[T](x: T)(s: String): String = {
    "happy " + s
  }

}

也编译。事情是在字节码级别上柯里化“消失”了,所以你最终得到:

def happyStuff(s: String): String

def happyStuff()(s: String): String

def happyStuff[T](x: T)(s: String): String

一样

def happyStuff[T](x: T, s: String): String

你可以做类似的事情

sealed trait Deprecated
object Deprecated {
  implicit val d: Deprecated = new Deprecated {}
}

object Happy {


  @deprecated("this is the old one")
  def happyStuff(s: String)(implicit d: Deprecated): String = {
    "happy " + s
  }

  def happyStuff()(s: String): String = {
    "happy " + s
  }

}

这样,相同的代码将适用于旧的实现......虽然它会改变签名,所以字节码的兼容性会丢失。或者,您可以想出其他一些“对代码进行版本控制”的方法,但最简单/最好的方法是更改​​名称(因为它会做其他事情)或签名。

于 2018-02-26T20:32:08.627 回答