Scala在擦除后解决相同类型的方法

时间:2018-02-26 19:59:25

标签: scala erasure

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

我有以下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):第6行的字符串和def happyStuff()(s:String):第10行的字符串在擦除后具有相同的类型"

这个黑客得到了我想要的结果:

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如何解决删除邮件?有没有更好的方法来达到预期的结果?

1 个答案:

答案 0 :(得分: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
  }

}

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

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
  }

}

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