这似乎是一个人为的问题,但这是因为我已将其从更大的程序中简化了。
我在环境类中已经有一个通用方法:
class Environment {
def obtain[T <: Element](param : Int)(implicit ctag : ClassTag[T]): Array[T] = { ... }
}
我也定义
abstract class Process[T <: Element : ClassTag] {
def run(input : Array[T]) : Array[_ <: Element]
}
和一些具体的课程
class Oxidation extends Process[Hydrogen] { ... }
class Reduction extends Process[Water] { ... }
现在,我想拥有一个Process集合并按顺序运行它们。这是我希望写的方式:
val myEnv = new Environment
val allProcesses : Seq[Process[_]] = Seq(new Oxidation, new Reduction)
allProcess.map(proc =>
val material = myEnv.obtain[proc.*SPECIFIC TYPE HERE*](1)
proc.run(material)
)
之所以不能将myEnv提供给proc(确实可以正确编译和执行),是因为我希望像这样优化程序:
val myEnv = new Environment
val allProcesses : Seq[Process[_]] = Seq(new Oxidation, new Reduction)
allProcess.map(proc =>
val material = myEnv.obtain[proc.*SPECIFIC TYPE HERE*](1)
proc.run(material)
anotherProc.run(material)
anotherProc2.run(material)
)
有任何线索吗?只要可以动态调用myEnv.obtain [someVariable],就可以重构程序的大部分内容。
我正在使用Scala 2.10.6。预先谢谢你!
答案 0 :(得分:1)
您需要为每个单独的Process
的TypeParameter使用ClassTag。
Process
类已经需要将这样的TypeTag[T]
隐式传递给其构造函数,您可以公开以下内容:
abstract class Process[T <: Element : ClassTag] {
def ctag: ClassTag[T] = implicitly[ClassTag[T]]
def run(input : Array[T]) : Array[_ <: Element] = { ... }
}
val myEnv = new Environment
val allProcesses: Seq[Process[_ <: Element]] = Seq(new Oxidation, new Reduction)
// This functions binds the type parameter of `proc` as `T`, so we can refer to it.
def doRun[T <: Element](proc: Process[T]) = {
val material = myEnv.obtain[T](1)(proc.ctag)
proc.run(material)
}
for (process ← allProcesses) yield doRun(process)