如何使用参数化类作为键来操作地图

问题描述

我试图定义一个以参数化类为其键的映射。但是当我尝试添加它时,出现编译器错误

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore')
raw_data = pd.read_csv('all-deep-soil-temperatures.csv',index_col=1,parse_dates=True)
df_all_stations = raw_data.copy()
df_selected_station.fillna(method = 'ffill',inplace=True);
df_selected_station_D=df_selected_station.resample(rule='D').mean()
df_selected_station_D['Day'] = df_selected_station_D.index.dayofyear
mean=df_selected_station_D.groupby(by='Day').mean()
mean['Day']=mean.index
mean.head()

我收到以下编译器错误

trait MyTrait[T <: MyTrait[T]]

case class A(i: Int) extends MyTrait[A]
case class B(str: String) extends MyTrait[B]

var map = Map[Class[_ <: MyTrait[_]],Int]()

def update[T <: MyTrait[T]](n: Int) = {
    map += classOf[T] -> n  // Won't compile
}

将类提取为键的正确方法是什么?如果我使用具体的类,例如,它将编译良好:

  Expression does not convert to assignment because:  
    class type required but T found  
    expansion: map = map.+(classOf[T].<$minus$greater: error>(n))  
        map += classOf[T] -> n  

解决方法

您应该添加上下文绑定的ClassTag并将classOf[T]替换为classTag[T].runtimeClass

classOf[T]适用于实际的类(现在称为类,例如classOf[Int]classOf[String]等)。对于类型参数(在调用方法时将成为类类型),您需要类标记。

def update[T <: MyTrait[T]: ClassTag](n: Int) = {
  val clazz = classTag[T].runtimeClass.asInstanceOf[Class[T]]
  map += clazz -> n
}

println(map) //HashMap()
update[A](1) 
println(map) //HashMap(class A -> 1)
update[B](2)
println(map) //HashMap(class A -> 1,class B -> 2)

https://docs.scala-lang.org/overviews/reflection/typetags-manifests.html