Grails3中将Groovy闭包作为方法参数调用报NoSuchMethodError如何解决
问题根源
你的思路是可行的,Closure完全可以作为方法参数传入,报错是Groovy的List.sort()方法重载匹配逻辑导致的:
Groovy的List.sort()有两类接受闭包的重载:
- 双参数比较器闭包:
sort { a, b -> /* 返回比较结果整数 */ },是优先级更高的匹配项 - 单参数key提取闭包:就是你用的
sort { it.id }这种,用来提取排序关键字段
你直接将外部传入的单参数闭包传给sort时,Groovy会优先匹配双参数的重载,你传入的闭包仅支持1个入参,自然找不到匹配的方法签名,就触发了NoSuchMethodError错误。
修复方案
调用sort时明确指定重载,第一个参数传布尔值表示是否修改原列表(你原本的sort {it.id}是修改原列表的,所以传true保持行为一致),第二个参数传你的排序闭包即可,修改后的代码如下:
List<Category> getCategories(List<Post> posts, Closure sortClosure = null) { List<Category> categories = ... // logic to get categories if (sortClosure == null) { categories.sort { it.id } } else { // 明确匹配单参数key提取闭包的重载 categories.sort(true, sortClosure) } return categories }
原有调用代码不需要修改,也可以按Groovy语法习惯把最后一个闭包参数写到括号外,写法更简洁:
List<Category> categories = postsService.getCategories(posts) { it.year }
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

