trait t{
val y = "z"
def t1(x:String):String=x+"a"+y
def t2(x:String):String= x+"b"+y
def t3(x:String):String= x+"c"+y
}
class c extends t {
val funcSet = Set(t1 _,t2 _,t3 _)
def multiBitamin(input:String) = for(f <- funcSet) yield f(input)
}
我希望在t1,t2,t3之间进行遍历,而不需要像funcSet这样的Set
val funcSet = Set("t1","t2","t3")
接受
答案 0 :(得分:1)
执行此操作的方法仍然是使用反射,虽然这可以为您提供一些其他方法(如下面的toString
):
scala> trait t{
| val y = "z"
| def t1(x:String):String=x+"a"+y
| def t2(x:String):String= x+"b"+y
| def t3(x:String):String= x+"c"+y
| }
defined trait t
scala> val inst = new t{}
scala> inst.getClass.getMethods.filter(_.getName.startsWith("t")) map { m => (s: String) => m.invoke(inst, s) }
然后使用结果遍历函数。当然,你可能比这更聪明,并根据参数的数量和类型过滤方法,并将包装器存储在底层地图中以访问它们。
编辑:
如果您有想要呼叫的方法的特定名称(例如t1
),您可以这样做:
scala> val f = (s: String) => inst.getClass.getMethods.find(_.getName == "t1").get.invoke(inst, s)
f: (String) => java.lang.Object = <function1>
另一种实现此目的的方法是,如果在编译时已知方法名称,则在调用点使用结构类型:
scala> (inst: AnyRef).asInstanceOf[{def t1(s: String): String}].t1("Hello ")
res9: String = Hello az
请注意,您不能像以前一样使用字符串。这也是在引擎盖下使用反射。
此外,Scala中添加了一个新的Dynamic
特征,其子类将允许使用在运行时获取的名称调用方法。这将在未来的某些版本中提供。