我正在尝试将代码转换为面向组件的设计。
我的争论点是以下函数do()
,该函数将其s
参数与一些先前已知的String
相匹配,并使用适当的类型参数调用compute()
。
def do(s: String, summoner: Summoner): String = {
s match {
case "a" => summoner.compute[Type_A](outOfScopeVal)
case "b" => summoner.compute[Type_B](outOfScopeVal)
case _ => ""
}
}
如果需要任何新的trait
,我想将其转置为通用extended
的{{1}}。
[EDIT]这将是一个库,外部开发人员可以随意充实,在String标识符和类型之间添加新的匹配项。
[EDIT2]我调用一个定义如下的库:
Type_x
此问题可以简化为获得一个通用工具,该工具根据输入的String返回(某种)
trait TypeHolder[T <: Type_top] {def score(...): String}
object Converters {
implicit object ConverterOfA extends TypeHolder[Type_A] {
def convertAndMore(...): String = {
/*
compute and return a String
*/
}
}
implicit object ConverterOfB extends TypeHolder[Type_B] {
def convertAndMore(...): String = {
/*
compute and return a String
*/
}
}
}
case class Summoner(...) {
def compute[T <: Type_top](...)(implicit summoner: TypeHolder[T]): String = {
summoner.convertAndMore(...)
}
}
。
这个问题:https://stackoverflow.com/a/23836385/3896166,接近预期的解决方案,但是我不能满足“提前知道对象映射名称的类型”的要求,因为输入字符串是动态接收的... < / p>
此外,type
可能是遵循的道路,但是我只是开始沿着这条道路走。
有可能吗?
答案 0 :(得分:1)
您可以通过将String
转换为type
(如果可能)来解决此问题,但这不是解决潜在问题的唯一方法。 (因此,这是XY question)
相反,您需要构建一个Map
,将您从String
带到一种计算适当函数的方法。它可能像这样工作:
def computeFn[T <: Type_top] =
(summoner: Summoner, value: ???) => summoner.compute[T](value)
val computeMap = Map(
"a" -> computeFn[Type_A],
"b" -> computeFn[Type_B]
)
def do(s: String, summoner: Summoner): String =
computeMap(s)(summoner, outOfScopeVal)
对此进行修改应该很简单,以便子类可以添加到computeMap
对象中以定义它们自己的映射。