Параметр типа класса стирания 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)
   }
}
Другие вопросы по тегам