如何创建 map[String,Class] 并在 Scala 中动态创建它的对象

How to create map[String,Class] and create its object dynamically in scala

场景: 我有一个 senario,我需要一个一个地调用 Processor class,这是用户输入提供程序所要求的,如果没有提供,它应该调用其中的所有 Processor class 和 process() 方法。

代码:

class OneProcessor{}
class TwoProcessor{}

为此,我正在考虑创建一个 Map[String, instanceOfClass] 即:

val instanceMap:Map[String,Class] =Map(
    "string1" -> new OneProcessor(),
    "string2" -> new TwoProcessor(),
)

问题: 如果用户给定 string1 我需要创建 OneProcessor() 的实例并执行它的 processor() 方法。

如果没有向用户提供任何输入,我需要调用 Map 的所有键,并创建所有 classes 的实例并调用所有...

的 processor()

如何在 scala 中执行此操作?

您可以调用 newInstance 方法从 class 中创建实例。

classOf[OneProcessor].newInstance

这是我的解决方案:

假设所有 "processors" 都在做类似的事情,我建议从特征而不是使用通用的 class 级别构造来扩展它们。让我们假设以下结构:

trait Processor {
  def process=println("default process")
}
case class ProcessorOne() extends Processor
case class ProcessorTwo() extends Processor {
  override def process=println("process 2")
}
case class ProcessorThree() extends Processor {
  override def process=println("process 3")
}

我们创建一个映射并将所有 process 函数放入其中:

val myFuncs =
  Map("string1" -> (() => ProcessorOne().process),
    "string2" -> (() => ProcessorTwo().process),
  "string3" -> (() => ProcessorThree().process))

请注意,这是 Map[String, Unit]。由于您的目标是调用函数,因此您实际上不需要将实例放入映射中。

现在您可以轻松调用以下任何或所有功能:

val userInput =""

if(myFuncs isDefinedAt userInput)
  myFuncs(userInput)()
else
  myFuncs.values.foreach(v => v())

以上将输出:

default process
process 2
process 3

因此,如果键不存在于映射中,将调用所有函数(无特定顺序),但如果键在映射中,则仅调用与该键关联的函数。

如果您还需要按特定顺序 运行 的函数,您可以使用 LinkedHasMapListMap 创建一个保留插入顺序的映射。