是否有任何Scala功能允许您调用其名称存储在字符串中的方法?

Geo*_*Geo 18 language-features scala dynamic

假设你有一个包含方法名称的字符串,一个支持该方法和一些参数的对象,是否有一些语言功能允许你动态调用它?

有点像Ruby的send参数.

Rex*_*err 32

您可以使用Java中的反射执行此操作:

class A {
  def cat(s1: String, s2: String) = s1 + " " + s2
}
val a = new A
val hi = "Hello"
val all = "World"
val method = a.getClass.getMethod("cat",hi.getClass,all.getClass)
method.invoke(a,hi,all)
Run Code Online (Sandbox Code Playgroud)

如果你希望它在Scala中变得简单,你可以创建一个为你做这个的类,加上一个隐含的转换:

case class Caller[T>:Null<:AnyRef](klass:T) {
  def call(methodName:String,args:AnyRef*):AnyRef = {
    def argtypes = args.map(_.getClass)
    def method = klass.getClass.getMethod(methodName, argtypes: _*)
    method.invoke(klass,args: _*)
  }
}
implicit def anyref2callable[T>:Null<:AnyRef](klass:T):Caller[T] = new Caller(klass)
a call ("cat","Hi","there")
Run Code Online (Sandbox Code Playgroud)

但是,这样做会将编译时错误转换为运行时错误(即它实际上绕过了类型系统),因此请谨慎使用.

(编辑:并在上面的链接中查看NameTransformer的使用 - 如果您尝试使用运算符,这将有所帮助.)


Jim*_*ows 6

是.它被称为反射. 这是一种方式的链接,使用一些实验性的东西 但是你应该记住,Scala不是一种动态语言,并且可能无法轻松地做一些脚本语言可以做的事情.你可能最好在字符串上进行匹配,然后调用正确的方法.