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