Groovy 带条件日志记录的闭包

Groovy 带条件日志记录的闭包,groovy,closures,Groovy,Closures,我有这样一个函数: private downloadAllFiles() { sftpRetriever.listFiles().findAll { filter.isResponse(it) || filter.isResponseTurned(it) }.each { String fileName -> log.info 'Downloading file: {}', fileName sftpRetriever.dow

我有这样一个函数:

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,它将只记录“无需下载的文件”和。每个文件都不会执行。有没有简单的方法可以在单个闭包中实现?如果我将其分为几个部分,这确实是一项简单的任务,但在这里尝试学习闭包并提高表达能力:)提前感谢您的帮助。

您可以尝试以下代码:

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)
defl1=[1,2,3,4]
def l2=[5,6,7,8]
def m(列表){
list.findAll{it<5}。带有{l->
大小>0?
l、 每个{e->
普林顿
}
: 
println('找到零个元素')
}
}
m(l1)
m(l2)

目前没有更好的主意。

一个相当通用且可重用的选项是使用。这是非常容易做到的,甚至在IDE中(至少在IntelliJ中)都可以识别,所以您可以完成代码,等等

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

package stackoverflow

class CollectionExtension {
    static <T extends Collection> T doIfEmpty(T self, Closure closure) {
        if (self.empty) {
            closure()
        }
        return self
    }
}
最后是一个简单的测试脚本,演示如何使用它:

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

printContents([1,2,'hello'])
printContents([])
输出:

1
2
hello
Collection is empty

看看下面的生物:)它之所以能工作,是因为它返回了调用它的集合(+非常好的Groovy):

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

您还可以使用添加Steinar提供的方法。在首次使用之前,必须将其添加到
元类
,但您可以避免使用扩展模块:

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([])

谢谢但我仍然希望它能以更简单的方式实现:)+1用于
;但是我宁愿使用一个好的ole
if
if(!l.size()){log();return}l.each{…
很好,真的很好。唯一的问题在于“扩展模块”的额外工作,无论如何也很好。@Opal:是的,如果你只使用一次,那么这样做就太过分了,但是如果你在几个不同的地方需要它,就没有太多额外的工作。当然,正如我前面所说的,我喜欢这个解决方案。你可以用
|
代替
?:
def printContents(Collection collection) {
    collection.each {
        println it
    } ?: println('Collection is empty')
}

printContents([1,2,'hello'])
printContents([])
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([])