使用 groovy.transform.Field 定义另一个字段

Using groovy.transform.Field to define another Field

我正在编写一个 Groovy 脚本,我需要在闭包中使用我的一些字段。下面是一个非常简单的例子来说明我的问题。

#!/usr/bin/env groovy

import groovy.transform.Field

@Field def first = 'one'
assert first == 'one'

到目前为止一切顺利。在我的真实案例中,这将包含一个表示服务器名称的字符串。然后我从命令行选项修改这个 "default" 值 - 使用 CliBuilder() - 可能是这样的:

first = 'two'
assert first == 'two'

这仍然有效。我现在需要根据上面的字段创建一个新字段:

@Field def second = first
assert second == 'two'

在我的真实案例中,这将是一个 HTTPBuilder(),我将使用它进行 REST 调用。

这失败了:

Assertion failed: 

assert second == 'two'
       |      |
       'one'  false

有没有办法让它工作?

以某种方式解决此问题的尝试失败了。使用中介,例如:

def intermediary = first
assert intermediary == 'two'
@Field def second = intermediary

失败:

Caught: java.lang.reflect.InvocationTargetException
java.lang.reflect.InvocationTargetException
    at something.main(something)
Caused by: groovy.lang.MissingPropertyException: No such property: intermediary for class: something
    at something.<init>(something)
    ... 1 more

注释 @Filed 声明了脚本 class 的成员,任何其他脚本命令将转到 script.run() 方法

例如脚本

import groovy.transform.Field

@Field def first = 'one'
first = 'two'
@Field def second = first
assert second == 'two' // <<<---- fails because second=='one'

在编译脚本的时候会大致变成这个class:

class scriptXXXX{
    Object first
    Object second

    scriptXXXX(){ // constructor
        first = 'one'
        second = first
    }

    void run(){ // script body
        first = 'two'
        assert second == 'two' : null    
    }
}

您可以通过按 Ctrl+T

groovyconsole 中看到它


作为变体,您可以将字段声明和初始化分开:

@Field def first = 'one'
@Field def second
first = 'two'
second = first
assert second == 'two'