Как я могу сопоставить шаблон на класс времени выполнения в Scala
У меня есть фрагмент кода, подобный этому:
override def getOption[T: TypeTag: ClassTag](path: String): Option[T] = {
implicitly[scala.reflect.ClassTag[T]].toString() match {
case "java.lang.String" => HandleBlank(super.getOption[String](path)).asInstanceOf[Option[T]]
case _ => super.getOption[T](path)
}
}
Я предполагаю, что должен быть лучший способ сделать это, чем сопоставление по строке, но попробовал несколько вещей (например, classOf[String]
) и не могу найти то, что работает.
Для контекста, getOption (в суперклассе, который мы пытаемся переопределить) получает значение Option из объекта JV4ue AST json4s
def getOption[T: TypeTag: ClassTag](path: String): Option[T] = Try(getJValue(path).extract[T]).toOption
def getJValue(path: String): JValue = {
path.split('.').foldLeft(value)((a, b) => a \ b) match {
case JNull => JNothing
case j => j
}
}
Идея состоит в том, что я хочу подправить его так, чтобы только для строковых типов этого метода мы хотели обрабатывать пустые строки особым образом.
2 ответа
Вы можете сделать прямые тесты на равенство между ClassTag
вот так:
override def getOption[T: TypeTag: ClassTag](path: String): Option[T] = {
// not required, just nicer to write classTag[T] vs. implicitly[ClassTag[T]]
import reflect.classTag
classTag[T] match {
case strTag if strTag == classTag[String] => HandleBlank(super.getOption[String](path)).asInstanceOf[Option[T]]
case _ => super.getOption[T](path)
}
}
Один из распространенных приемов - поместить значение, с которым вы хотите сравнить, в локальную переменную или поле:
import scala.reflect.classTag
val StringTag = classTag[String]
override def getOption[T: TypeTag: ClassTag](path: String): Option[T] = {
classTag[T] match {
case StringTag => ...
case _ => ...
}
}
Обратите внимание, что имя должно начинаться с заглавной буквы, в противном случае case stringTag
просто свяжет новую переменную (хотя вы можете окружить stringTag
с `чтобы исправить это).