groovy - Groovy:如何使用类的内部枚举作为类外的参数类型
问题描述
Given 是一个EnumTest
声明内部枚举的类MyEnum
。
在类中使用MyEnum
作为参数类型按预期工作。
MyEnum
在外部用作参数类型EnumTest
无法使用unable to resolve class test.EnumTest.MyEnum
.
我浏览了相关问题,其中最好的一个是this,但它们没有解决使用枚举作为类型的具体问题。
我是否在这里遗漏了一些非常明显的东西(因为我对 Groovy 很陌生)?或者这只是该语言关于枚举的另一个怪癖 “增强” ?
编辑:这只是一个演示问题的测试。实际问题发生在 Jenkins JobDSL 中,否则类路径和导入似乎很好。
Groovy Version: 2.4.8
JVM: 1.8.0_201
Vendor: Oracle Corporation
OS: Linux
$ tree test
test
├── EnumTest.groovy
├── File2.groovy
└── File3.groovy
EnumTest.groovy:
package test
public class EnumTest {
public static enum MyEnum {
FOO, BAR
}
def doStuff(MyEnum v) {
println v
}
}
文件 2.groovy:
package test
import test.EnumTest
// prints BAR
new EnumTest().doStuff(EnumTest.MyEnum.BAR)
// prints FOO
println EnumTest.MyEnum.FOO
文件 3.groovy:
package test
import test.EnumTest
// fails: unable to resolve class test.EnumTest.MyEnum
def thisShouldWorkIMHO(EnumTest.MyEnum v) {
println v
}
当我使用 运行测试文件groovy -cp %
时,输出如下:
# groovy -cp . File2.groovy
BAR
FOO
# groovy -cp . File3.groovy
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
/home/lwille/-/test/GroovyTest2.groovy: 6: unable to resolve class EnumTest.MyEnum
@ line 6, column 24.
def thisShouldWorkIMHO(EnumTest.MyEnum v) {
^
1 error
解决方案
有几点值得一提。您不需要从同一个包中导入类。其次,当您使用包时,test
您需要从根文件夹执行 Groovy,例如groovy test/File3.groovy
正确设置类路径。(在这种情况下无需使用-cp .
)。
这是它应该的样子。
$ tree test
test
├── EnumTest.groovy
├── File2.groovy
└── File3.groovy
0 directories, 3 files
测试/EnumTest.groovy
package test
public class EnumTest {
public static enum MyEnum {
FOO, BAR
}
def doStuff(MyEnum v) {
println v
}
}
测试/File2.groovy
package test
// prints BAR
new EnumTest().doStuff(EnumTest.MyEnum.BAR)
// prints FOO
println EnumTest.MyEnum.FOO
测试/File3.groovy
package test
// fails: unable to resolve class test.EnumTest.MyEnum
def thisShouldWorkIMHO(EnumTest.MyEnum v) {
println v
}
thisShouldWorkIMHO(EnumTest.MyEnum.BAR)
控制台输出:
$ groovy test/File2.groovy
BAR
FOO
$ groovy test/File3.groovy
BAR
但是,如果要从test
文件夹内执行脚本,则需要指定类路径以指向父文件夹,例如:
$ groovy -cp ../. File3.groovy
BAR
$ groovy -cp . File3.groovy
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
/home/wololock/workspace/groovy-sandbox/src/test/File3.groovy: 4: unable to resolve class EnumTest.MyEnum
@ line 4, column 24.
def thisShouldWorkIMHO(EnumTest.MyEnum v) {
^
1 error
更新:Groovy 2.4 和 2.5 版本之间的区别
值得一提的是——上述解决方案适用于 Groovy 2.5.x及更高版本。重要的是要了解方法参数类型检查等事情发生在编译器Phase.SEMANTIC_ANALYSIS
阶段。在 Groovy 2.4 版本中,语义分析类解析发生在不加载类的情况下。在使用内部类的情况下,加载其外部类以便解决问题至关重要。Groovy 2.5 解决了这个问题(有意或无意),语义分析解决了内部类,而没有在这个问题中提到的问题。
有关更详细的分析,请检查以下 Stack Overflow 问题GroovyScriptEngine throws MultipleCompilationErrorsException while loading class that uses other class' static internal class我调查了在 Groovy 2.4 脚本中发现的类似问题。我在那里一步一步地解释了如何挖掘这个问题的根源。
推荐阅读
- python - 在转换为 json 格式之前,我想按我的数据框在两个不同的级别进行分组
- haskell - Haskell 中的 Lambda 演算 isEven 函数
- javascript - 如何修复 CRUD 应用程序中的 404(未找到)错误?
- boolean - 如何在 Liferay 7 中存储公司范围的单个变量?
- php - 当数据库有新行时显示通知,Laravel
- python - python错误:TypeError:+的不支持的操作数类型:'NoneType'和'int'。如何解决这个问题?
- javascript - 将“活动”类添加到与当前单击的侧边栏菜单链接相同的 href
- makefile - 如何在嵌套的 makefile 中覆盖 makefile
- r - 围绕一个值对相邻值进行子集
- c# - AutoCompleteTextView(只有创建视图层次结构的原始线程才能接触其视图。)