如何在scala中获取方法列表

时间:2010-05-22 00:37:57

标签: scala

在像python和ruby这样的语言中,要求语言它的字符串类支持哪些与索引相关的方法(哪些方法的名称包含单词“index”),你可以这样做

“”.methods.sort.grep /index/i

在java中

List results = new ArrayList();  
Method[] methods = String.class.getMethods();  
for (int i = 0; i < methods.length; i++) {  
    Method m = methods[i];  
    if (m.getName().toLowerCase().indexOf(“index”) != -1) {  
        results.add(m.getName());  
    }  
}  
String[] names = (String[]) results.toArray();  
Arrays.sort(names);  
return names;  

你会如何在Scala中做同样的事情?

6 个答案:

答案 0 :(得分:43)

很奇怪没人试过更直接的翻译:

""
.getClass.getMethods.map(_.getName) // methods
.sorted                             // sort
.filter(_ matches "(?i).*index.*")  // grep /index/i

所以,一些随意的想法。

  • “方法”和上面的箍之间的区别是惊人的,但没有人说过反射是Java的力量。

  • 我隐藏了一些关于sorted的内容:它实际上采用了Ordering类型的隐式参数。如果我想对方法本身进行排序而不是对其名称进行排序,我必须提供它。

  • grep实际上是filtermatches的组合。由于Java决定匹配整个字符串,即使未指定^$,它也会变得更复杂一些。我认为在grep上设置Regex方法是有道理的,该方法将Traversable作为参数,但是......

所以,这就是我们可以做的事情:

implicit def toMethods(obj: AnyRef) = new { 
  def methods = obj.getClass.getMethods.map(_.getName)
}

implicit def toGrep[T <% Traversable[String]](coll: T) = new {
  def grep(pattern: String) = coll filter (pattern.r.findFirstIn(_) != None)
  def grep(pattern: String, flags: String) = {
    val regex = ("(?"+flags+")"+pattern).r
    coll filter (regex.findFirstIn(_) != None)
  }
}

现在这是可能的:

"".methods.sorted grep ("index", "i")

答案 1 :(得分:10)

您可以使用scala REPL提示符。例如,要查找字符串对象的成员方法列表,请键入&#34;&#34;。然后按TAB键(这是一个空字符串 - 如果你愿意,甚至是非空字符串,然后按一个点,然后按TAB键)。 REPL将为您列出所有成员方法。

这也适用于其他变量类型。

答案 2 :(得分:5)

或多或少地以同样的方式:

val names = classOf[String].getMethods.toSeq.
    filter(_.getName.toLowerCase().indexOf(“index”) != -1).
    map(_.getName).
    sort(((e1, e2) => (e1 compareTo e2) < 0))

但一切都在一条线上。

为了使其更具可读性,

val names = for(val method <- classOf[String].getMethods.toSeq
    if(method.getName.toLowerCase().indexOf("index") != -1))
    yield { method.getName }
val sorted = names.sort(((e1, e2) => (e1 compareTo e2) < 0))

答案 3 :(得分:3)

现在,等一下。

我承认,与Ruby相比,Java是冗长的。

但是这段代码首先应该不那么冗长。

这是等效的:

    Collection<String> mds = new TreeSet<String>();
    for( Method m : "".getClass().getMethods()) {
        if( m.getName().matches(".*index.*")){  mds.add( m.getName() ); }
    }

其中包含与标记为正确的Scala版本

几乎相同的字符数

答案 4 :(得分:2)

据我所知:

"".getClass.getMethods.map(_.getName).filter( _.indexOf("in")>=0)  

奇怪的是,Scala数组没有排序方法。

修改

最终会像。

"".getClass.getMethods.map(_.getName).toList.sort(_<_).filter(_.indexOf("index")>=0)

答案 5 :(得分:1)

直接使用Java代码可以获得大部分内容,因为Scala类仍然是JVM类。不过,你可以很容易地将代码移植到Scala,以便在REPL中使用/练习/易用。