Обход Scala для методов с тем же типом после стирания

Я понял, как использовать 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 ответ

Это был не тег типа, а дополнительный параметр, который вы там указали:

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
  }

}

Таким образом, тот же код будет работать для старой реализации... хотя он изменит сигнатуру, поэтому совместимость с байт-кодом будет потеряна. В качестве альтернативы, вы могли бы придумать какой-то другой способ "создания версий кода", но самый простой / лучший способ - это либо изменить имя (как оно делает что-то еще), либо подпись.

Другие вопросы по тегам