试图了解Scala中的ClassTag和TypeTag

时间:2019-03-25 00:10:33

标签: scala

我试图了解如何使用public class MyTask extends AsyncTask<Void, Void, Void> { private MyViewModel viewModel; public MyTask(Application application){ viewModel = new MyViewModel(application); } @Override protected Void doInBackground(Void... voids) { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(Void aVoid) { super.onPostExecute(aVoid); viewModel.setNameData("Done task"); } } ClassTag克服Scala中的类型擦除。我编写了以下示例,这些示例是通用函数,试图滤除TypeTag等于List[TNode]的{​​{1}}。但是,我希望在TNode中,该函数将不会调用TMatch,因为该列表的通用类型等于recognizeUsingTypeTag(或消息被打印),但是我的假设显然是错误的。谢谢。

extractUsingClassTag

控制台:

TMatch

1 个答案:

答案 0 :(得分:1)

  

为什么没有为Lis​​t [String]打印此内容

因为您指定了显式类型参数:[Any, String],所以case _ if typeOf[TNode] =:= typeOf[TMatch]比较了typeOf[Any] =:= typeOf[String]

由于您确实需要为String指定TMatch,但是希望推断出TNode,因此通常的做法是通过创建中间类将类型参数分成两个列表:

// in Extractor
class RecognizeUsingTypeTag[TMatch : TypeTag : ClassTag] {
  def apply[TNode : TypeTag : ClassTag](list: List[TNode]) = list match {
    case _ if typeOf[TNode] =:= typeOf[TMatch] => {
      //
      // Why this does not get printed for List[String]
      //
      println("This should get printed when called for homogeneous")
      list.asInstanceOf[List[TMatch]]
    }
    case _ => extractUsingClassTag[TNode, TMatch](list)
  }
}

def recognizeUsingTypeTag[TMatch : TypeTag : ClassTag] = new RecognizeUsingTypeTag[TMatch]


println(Extractor.recognizeUsingTypeTag[String].apply(homogeneous)) // inferred as apply[String]
println(Extractor.recognizeUsingTypeTag[String].apply(heterogeneous) + "\n") // inferred as apply[Any]

当您具有诸如这样的隐式参数并且不需要其名称时,最好使用context boundsT : TypeTag : ClassTag添加两个类型为{{1}的隐式参数}和TypeTag[T]