Groovy : 如何修改闭包中的值(类似于 shell pipe)

groovy : how to modfiy value in closure ( similar with shell pipe )

提问人:Marslo 提问时间:1/5/2023 最后编辑:Marslo 更新时间:1/6/2023 访问量:40

问:

为了简化代码,我尝试使用类似于管道的用法,如下所示:

  • foo( 'abc' ) -> 'abc ~> 123'(默认结果)
  • foo( 'abc' ).bar( 'efg' ) -> 'efg : abc ~> 123'(必要时增加)

因此,我尝试使用Map + Closure进行如下处理:

def foo ( String aStr ) {
    String constant = '123'
    String result = "${aStr} ~> ${constant}"

    [
        bar : { String bStr -> result = "${bStr} : ${result}"; return result }
    ]
    println result
}

foo( 'abc' )                    // abc ~> 123
foo( 'abc' ).bar( 'efg' )       // java.lang.NullPointerException: Cannot invoke method bar() on null object

第二次尝试

我在地图结构中添加了默认键,如下所示。但是,它运行良好:

  • 呼叫两次println
  • 必须添加额外的键值default
def foo ( String aStr ) {
    String constant = '123'
    String result = "${aStr} ~> ${constant}"
    
    [
        bar     : { String bStr -> result = "${bStr} : ${result}"; println "${result}" } ,
        default : { println result }
    ]
}

foo( 'abc' ).bar( 'efg' )          // efg : abc ~> 123
foo( 'abc' ).default()             // abc ~> 123

第三次尝试

make 允许非参数,因此可以调用为 ,但 stills 不能直接调用barfoo(..).bar()foo(..)

def foo ( String aStr ) {
    String constant = '123'
    String result = "${aStr} ~> ${constant}"

    [
        bar : { String bStr = '' -> result = "${bStr ? "${bStr} : " : ''}${result}"; return result }
    ]
}

foo( 'abc' )                 // [bar:ConsoleScript22$_foo_closure1@5e7667fd]
foo( 'abc' ).bar()           // abc ~> 123
foo( 'abc' ).bar( 'efg' )    // efg : abc ~> 123

有没有更好的解决方案?

时髦 的开合

评论


答:

1赞 tim_yates 1/6/2023 #1

不是 100% 确定我是否掌握了这个问题,但你可以编写一个生成元素链的帮助程序类

class Result {
    String name
    def value

    def bar(String aStr) {
        new Result(name: aStr, value: this)
    }

    @Override
    String toString() {
        if (value instanceof String) {
            return "${name} ~> ${value}"
        } else {
            return "${name} : ${value?.toString()}"
        }
    }
}

然后,您的 Foo 方法变为:

Result foo(String aStr) {
    new Result(name: aStr, value: '123')
}

并调用以下命令,打印以下结果:

println foo('abc')
println foo('abc').bar('efg')
println foo('abc').bar('efg').bar('hahaha')
abc ~> 123
efg : abc ~> 123
hahaha : efg : abc ~> 123

评论

0赞 Marslo 1/6/2023
多谢!使用确实一个很好的解决方案!Class