使用条件记录关闭

时间:2014-09-03 09:49:33

标签: groovy closures

我有这样的功能:

private downloadAllFiles() {
    sftpRetriever.listFiles().findAll {
        filter.isResponse(it) || filter.isResponseTurned(it)
    }.each { String fileName ->
        log.info 'Downloading file: {}', fileName
        sftpRetriever.downloadFile(fileName)
        log.info 'File downloaded'
        removeRemoteFile(fileName)
    }
}

我正在寻找一种简单的方法来修改该函数内部的闭包,所以如果findAll的size()为0,它只会记录'没有更多的文件可供下载'而且.each将不会被执行。是否有任何简单的方法可以在单一闭包中制作它?如果我将它分成几个部分,但尝试在这里学习闭包并提高我的表现力,这真的是一项任务:)请事先感谢你的帮助。

3 个答案:

答案 0 :(得分:4)

一个相当通用且可重复使用的选项是使用extension module扩展Collection。这非常容易实现,甚至可以在IDE中识别(至少在IntelliJ中),因此您可以获得代码完成等。

例如,为集合编写扩展类,如果集合为空,将执行闭包。另外,它应该总是返回集合以允许进一步链接:

package stackoverflow

class CollectionExtension {
    static <T extends Collection> T doIfEmpty(T self, Closure closure) {
        if (self.empty) {
            closure()
        }
        return self
    }
}

您还需要告诉groovy此文件是扩展模块。在类路径中添加属性文件作为资源:META-INF/services/org.codehaus.groovy.runtime.ExtensionModule(注意:此名称和位置对于扩展模块是必需的,即您无法更改它。)

moduleName=stackoverflow-module
moduleVersion=1.0
extensionClasses=stackoverflow.CollectionExtension

最后一个简单的测试脚本来说明如何使用它:

def printContents(Collection collection) {
    collection.doIfEmpty {
        println "Collection is empty"
    }.each {
        println it
    }
}

printContents([1,2,'hello'])
printContents([])

输出:

1
2
hello
Collection is empty

答案 1 :(得分:4)

看看下面的生物:)它的工作原因是each返回了它被调用的集合(+ elvis operator和非常好的Groovy&#39; s {{ 3}}):

def printContents(Collection collection) {
    collection.each {
        println it
    } ?: println('Collection is empty')
}

printContents([1,2,'hello'])
printContents([])

我不喜欢这种语法,但它是我想到的较短版本。

您还可以使用truth evaluation添加Steinar提供的方法。首次使用前必须将其添加到metaClass,但您要避免努力制作扩展模块:

Collection.metaClass.doIfEmpty { Closure ifEmptyClosure ->
        if (delegate.empty) {
            ifEmptyClosure()
        }
        return delegate
}

def printContents(Collection collection) {
    collection.doIfEmpty {
        println "Collection is empty"
    }.each {
        println it
    }
}

printContents([1,2,'hello'])
printContents([])

答案 2 :(得分:3)

您可以尝试以下代码:

def l1 = [1,2,3,4]
def l2 = [5,6,7,8]

def m(list) {
    list.findAll { it < 5}.with { l ->
        size > 0 ? 
            l.each { e ->
                println e  
            }
        : 
            println('Zero elements found')
    }
}

m(l1)
m(l2)

目前没有更好的主意。