简体   繁体   中英

How can I initialize a generic variable in scala

As we all know, we can initialize a object of template parameter T in C++.

template <typename T>
struct Cont{
    T t;
}

I want to do the same in scala, so I write the following codes. There are some other classes which extends Evaluator , and EvaluateComponent is something like a wrapper. I can write code like new EvaluateComponent[BinaryClassificationEvaluator].evaluate(df)

abstract class Evaluator extends Serializable{
  var predCol = "prediction"
  var trueCol = "label"
  def evaluate(dataset: DataFrame) : String
  def evaluateRDD(dataset: RDD[(Double, Double)]) : String
}

class EvaluateComponent[E <: Evaluator : ClassTag] {
  val evaluator = new E
}

class BinaryClassificationEvaluator extends Evaluator {
  ...
}

However it doesn't compile with error class type required but E found . The post does not solve my question because I want evaluator to be initialized.

The limitation in Scala is the same as Java - generic type is erased at compile time, and no direct access to a class constructor like C++. But it can be done, through Java reflection:

abstract class Evaluator extends Serializable{}

class EvaluateComponent[E <: Evaluator : ClassTag] {
  val evaluator = implicitly[ClassTag[E]].runtimeClass.newInstance().asInstanceOf[E]
}

class BinaryClassificationEvaluator extends Evaluator {}

new EvaluateComponent[BinaryClassificationEvaluator].evaluator // Returns a BinaryClassificationEvaluator

This being said doesn't mean it is a good approach. The takeaways are:

  • The passed class in the generic parameter must have a default constructor. There will be runtime exception if it doesn't
  • Reflection is slower than normal code

Different language program in different mentality. It is better to implement this using type class in Scala but it's another topic.


EDIT:

Class.newInstance is deprecated now. Use Class.getDeclaredConstructor().newInstance() instead

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM