Scala擦除类类型参数

时间:2014-11-07 22:34:51

标签: scala type-parameter erasure

我有以下设置:

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)
   }
}

我似乎无法让typecheck工作。 我尝试将一个隐式TypeTag添加到Test [A]但我无法从proccess中访问它。 是否可以在过程函数中匹配Test的类型参数?

3 个答案:

答案 0 :(得分:2)

为此目的使用ClassTagmatch

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 _       =>
    }
  }
}

由于范围内隐含ClassTagmatch可以区分A,即使它是通用的。

答案 1 :(得分:0)

使用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上进行模式匹配。

答案 2 :(得分:0)

我不确定为什么data必须属于Any类型(用户输入的类型不是String?),但是如果确实如此,那么它可能反映了在编译时无法预测类型的情况。在这种情况下,您可能希望该方法在尝试强制转换时抛出运行时错误:

class Test[A](function: A => String) {
   def process(data: Any) = {
      function(data.asInstanceOf[A]) //might throw an error
   }
}

或者可能使用Try monad:

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)
   }
}