Scala - Passing Class of derived type in place of

2019-08-14 02:20发布

问题:

So, I have the following use case.

There is a class called SinglePredictionTester with the following implementaion.

class SinglePredictorTester[T <: Class[SurvivalPredictor]](predictorClass: T,
                                                            dataSplitter: DataSplitter,
                                                            titanic: DataFrame) extends PredictionTester {

  import titanic.sqlContext.implicits._

  override def test: Map[SurvivalPredictor, Double] = ???

}

The idea is for this class is to take a subclass of SurvivalPredictor class, instantiate it inside and execute some methods to test it's accuracy.

SurvivalPredictor has many implementations.

I plan to call the SinglePredictionTester like this:

  val test: Map[SurvivalPredictor, Double] = new SinglePredictorTester(classOf[SexBasedPredictor],
    new DataSplitter {},
    new DataFrameLoader {}.load(getPathForResource("train.csv"),
      sqlContext)).test

However this doesn't compile and gives me following error:

Error:(13, 46) inferred type arguments [Class[com.dhruvk.kaggle.predictors.implementations.SexBasedPredictor]] do not conform to class SinglePredictorTester's type parameter bounds [T <: Class[com.dhruvk.kaggle.predictors.SurvivalPredictor]]
  val test: Map[SurvivalPredictor, Double] = new SinglePredictorTester(classOf[SexBasedPredictor],
                                             ^

I'm unable to figure out how to get this working.

回答1:

The problem is that Class is not covariant in its generic type parameter. However, you can solve the problem by specifying T <: SurvivalPredictor.

class SinglePredictorTester[T <: SurvivalPredictor](
    predictorClass: Class[T],
    dataSplitter: DataSplitter,
    titanic: DataFrame) extends PredictionTester {

  import titanic.sqlContext.implicits._

  override def test: Map[SurvivalPredictor, Double] = ???
}


标签: scala