【问题标题】:Is it possible to get the name of variable in Groovy?是否可以在 Groovy 中获取变量的名称?
【发布时间】:2019-08-24 01:41:33
【问题描述】:

我想知道是否可以检索变量的名称。

例如,如果我有一个方法:

def printSomething(def something){
//instead of having the literal String something, I want to be able to use the name of the variable that was passed
println('something is: ' + something)
}

如果我这样调用这个方法:

 def ordinary = 58
 printSomething(ordinary)

我想得到:

ordinary is 58

另一方面,如果我这样调用这个方法:

def extraOrdinary = 67
printSomething(extraOrdinary)

我想得到:

extraOrdinary is 67

编辑

我需要变量名,因为我有这个在 Katalon Studio 中的每个 TestSuite 之前运行的代码 sn-p,基本上它为您提供了使用传递 GlobalVariables 的灵活性一个katalon.features 文件。思路来自:kazurayam/KatalonPropertiesDemo

  @BeforeTestSuite
    def sampleBeforeTestSuite(TestSuiteContext testSuiteContext) {
        KatalonProperties props = new KatalonProperties()
        // get appropriate value for GlobalVariable.hostname loaded from katalon.properties files
        WebUI.comment(">>> GlobalVariable.G_Url default value: \'${GlobalVariable.G_Url}\'");

//gets the internal value of GlobalVariable.G_Url, if it's empty then use the one from katalon.features file
            String preferedHostname = props.getProperty('GlobalVariable.G_Url')
            if (preferedHostname != null) {
                GlobalVariable.G_Url = preferedHostname;
                WebUI.comment(">>> GlobalVariable.G_Url new value: \'${preferedHostname}\'");
            } else {
                WebUI.comment(">>> GlobalVariable.G_Url stays unchanged");
            }
 //doing the same for other variables is a lot of duplicate code
        }

现在这只处理 1 个变量值,如果我为 20 个变量执行此操作,那就是很多重复的代码,所以我想创建一个辅助函数:

def setProperty(KatalonProperties props, GlobalVariable var){
   WebUI.comment(">>> " + var.getName()" + default value: \'${var}\'");

//gets the internal value of var, if it's null then use the one from katalon.features file
            GlobalVariable preferedVar = props.getProperty(var.getName())
            if (preferedVar != null) {
                var = preferedVar;
                WebUI.comment(">>> " + var.getName() + " new value: \'${preferedVar}\'");
            } else {
                WebUI.comment(">>> " + var.getName() + " stays unchanged");
            }
}

这里我只是放了 var.getName() 来解释我在寻找什么,这只是我假设的一种方法。

【问题讨论】:

  • @Carcigenicate 这不是纯粹出于好奇,我需要使用变量名将其传递给函数:KatalonProperties.getProperty(String key),它根据属性名称检索属性的值。我可以将参数更改为字符串而不是 def 来控制传递给我的函数的内容...但我仍然需要知道如何获取变量的名称
  • 不,不可能
  • @tim_yates 好吧,那真是太糟糕了:(
  • @AdityaT 不要认为它是重复的。那是关于获取参数名称。这是关于获取传递给方法的变量的名称
  • @tim_yate 用宏方法不可能,还是我错了?

标签: groovy metaprogramming katalon-studio


【解决方案1】:

是的,这可以通过 ASTTransformations 或宏 (Groovy 2.5+) 实现。

我目前没有合适的开发环境,但这里有一些指针:

并不是说这两个选项都不是微不足道的,不是我推荐的 Groovy 新手,你必须做一些研究。如果我没记错的话,任何一个选项都需要与您的调用代码分开构建/项目才能可靠地工作。此外,它们中的任何一个都可能会给您带来晦涩难懂且难以调试的编译时错误,例如,当您的代码需要变量作为参数但传递了文字或方法调用时。所以:有龙。话虽这么说:我在这些东西上做了很多工作,它们真的很有趣;)

Groovy Documentation for Macros

如果您使用的是 Groovy 2.5+,则可以使用宏。对于您的用例,请查看@Macro methods 部分。您的方法将有两个参数:MacroContext macroContext, MethodCallExpression callExpression 后者是有趣的参数。 MethodCallExpression 具有getArguments()-Methods,它允许您访问作为参数传递给方法的抽象语法树节点。在您的情况下,应该是 VariableExpression,它具有 getName() 方法来为您提供您正在寻找的名称。

Developing AST transformations

这是更复杂的版本。您仍然会得到与使用宏方法相同的VariableExpression,但到达那里会很乏味,因为您必须自己识别正确的MethodCallExpression。您从ClassNode 开始,然后自己前往VariableExpression。我建议使用本地转换并创建注释。但识别正确的MethodCallExpression 并非易事。

【讨论】:

  • 对于我的专业水平来说,这听起来工作量太大了 :(
  • 并不是要劝阻你:/但也许最好先学习基础知识,然后再回来。 Groovy 非常强大,当您开始使用 AST 时会变得更加强大;)
【解决方案2】:

没有。这是不可能的。

但是考虑使用 map 作为参数并传递属性的名称和值:

def printSomething(Map m){
    println m
}

printSomething(ordinary:58)
printSomething(extraOrdinary:67)
printSomething(ordinary:11,extraOrdinary:22)

这将输出

[ordinary:58]
[extraOrdinary:67]
[ordinary:11, extraOrdinary:22]

【讨论】:

  • 错误答案。可以获取变量名。
  • 抱歉,伙计,我实际上弄错了问题,对,我不确定它是否可能。 :D您能否编辑答案以阐明它可能用于方法参数但不能用于变量名称的观点。 :)
  • @AdityaT 如果可以使用方法参数,那么我也可以使用它。
  • 好的,我会添加一个答案。
  • @AdityaT 期待您的回答。
猜你喜欢
  • 2015-06-15
  • 2020-07-17
  • 1970-01-01
  • 1970-01-01
  • 2017-03-06
  • 1970-01-01
  • 2017-10-20
  • 2018-06-22
  • 2018-08-15
相关资源
最近更新 更多