微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

groovy(grails)中的递归

我试图在groovy中使用递归来遍历树关系.下面的代码运行一个周期,直到childNodes&& recurClosure(childNodes),但不会再次调用闭包recurClosure.在那一瞬间,childNodes有两个与root相同的对象(数组列表).

代码中,定义了recurClosure并使用对象列表(root)进行调用.然后迭代遍历每个元素并对子节点进行罚款(为此使用grails dsl).如果childNodes不为null,则递归调用方法.

我应该分手,还是出了什么问题?

def parentval 
def root = Domain.list()

def recurClosure
recurClosure = {inroot ->
  inroot.each {
    returnList << it
    parentval = it
    childNodes = Domain.withCriteria {
      eq('parent',parentval )
    }
  }
  childNodes && recurClosure(childNodes )
}(root)

return returnList

}

提前致谢.

更新:注意到以下异常

ERROR [2010-06-24 08:20:04,742] [groovy.grails.web.errors.GrailsExceptionResolver] Cannot invoke method call() on null object
java.lang.NullPointerException: Cannot invoke method call() on null object
    at com.bsr.test.DomainService$_closure2_closure7.doCall(com.bsr.test.DomainService:68)
    at com.bsr.test.DomainService$_closure2.doCall(com.bsr.test.DomainService:58)
    at com.bsr.test.DomainController$_closure3.doCall(DomainController.groovy:45)
    at com.bsr.test.DomainController$_closure3.doCall(DomainController.groovy)
    at org.apache.shiro.web.servlet.ShiroFilter.executeChain(ShiroFilter.java:687)
    at org.apache.shiro.web.servlet.ShiroFilter.doFilterInternal(ShiroFilter.java:616)
    at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:81)
    at java.lang.Thread.run(Thread.java:619)

更新2:现在尝试丹尼尔的建议.

{ inroot ->
    inroot.each {
        returnList << it
        parentval = it
        childNodes = Domain.withCriteria {
            eq('parent',parentval )
        }
           if(childNodes)
           call(childNodes)
    }
       /*if(childNodes)
        call(childNodes)*/

}(root)

在上面的实现中,root是一个arraylist,内部闭包从它中取出每个元素并递归调用匿名闭包.当我在每个闭包内移动’call’时,它不会调用外部匿名闭包,而是调用inroot.each {}本身.所以,我得到一个错误

ERROR [2010-06-24 08:47:46,438] [groovy.grails.web.errors.GrailsExceptionResolver] instance not of expected entity type: java.util.ArrayList is not a: com.bsr.test.Domain

我看到一篇关于如何通过‘this’>命名封闭的博客文章.我会更新我的发现..谢谢

更新3:调用外部闭包的方法是owner.call(childNodes)

解决方法

问题是,通过

recurClosure = {
    [...]
}(root)

你没有将闭包分配给recurClosure,而是将其调用的返回值分配给它!因此,当然,你不能通过recurClosure()调用闭包…

两种可能的解决方

首先定义闭包,然后单独调用它,如air_blob建议:

def recurClosure = {
    [...]
}
recurClosure(root)

使用隐式call()函数进行递归.这样你甚至可以使用匿名闭包.恕我直言在Groovy中实现递归的一种非常好的方法

{ inroot ->
    inroot.each {
        returnList << it
        parentval = it
        childNodes = Domain.withCriteria {
            eq('parent',parentval )
        }
    }
    if(childNodes)
        call(childNodes)
}(root)

还有两条关于代码评论

>您可能想要声明returnList:def returnList = []
>而childNodes&& recurClosure(childNodes)可以做你想要的,更可读的是牺牲一个更多的char并拼出if ..

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐