Параметр типа класса стирания Scala
У меня есть следующие настройки:
class Test[A](function: A => String) {
def process(data: Any) { //has to be Any since it is user IO
if (data of Type A)
function(data)
}
}
Я не могу заставить работать проверку типов. Я попытался добавить неявный TypeTag в Test[A], но не смог получить к нему доступ изнутри процесса. Можно ли сопоставить параметр типа Test внутри функции процесса?
3 ответа
Использовать ClassTag
а также match
для этой цели:
import scala.reflect.ClassTag
class Test[A : ClassTag](function: A => String) {
def process(data: Any) { //has to be Any since it is user IO
data match {
case data: A => function(data)
case _ =>
}
}
}
Благодаря скрытому ClassTag
по объему match
может различать A
хотя это универсально.
Используя Shapeless:
class Test[A: Typeable](function: A => String){
import shapeless.syntax.typeable._
def process(data: Any) { //has to be Any since it is user IO
data.cast[A] map { function(_) }
}
}
Этот метод безопасен, так как он возвращает Option[A], поэтому, если приведение не выполнено, вы можете сопоставить шаблон с None.
Я не уверен почему data
должен быть типа Any
(пользовательский ввод не будет иметь тип String
?), но если это действительно так, то, вероятно, это отражает ситуацию, когда тип не может быть ожидаем во время компиляции. В таком случае вы, вероятно, захотите, чтобы метод выдавал ошибку времени выполнения при попытке привести:
class Test[A](function: A => String) {
def process(data: Any) = {
function(data.asInstanceOf[A]) //might throw an error
}
}
Или, возможно, использовать Try
монада:
class Test[A](function: A => String) {
def process(data: Any) = {
Try(function(data.asInstanceOf[A]))
}
}
Конечно, наиболее предпочтительным было бы знать тип data
во время компиляции:
class Test[A](function: A => String) {
def process(data: A) = {
function(data)
}
}