- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试在 Groovy 中开发一个项目,并且我一直在查看我的代码并试图找到可以用更惯用的 Groovy 替换的区域,直到我找到 another issue I've been having 的解决方案。 .
我已经开始更深入地研究 AST 转换注释的使用 - 它们帮助显着减少了我必须在某些地方编写的代码量。但是,我在使用 groovy.transform.builder.Builder
时遇到了问题使用我的不可变值类之一进行注释。此注释的来源托管 here .
问题是注释似乎使构建器直接设置构建者的值,而不是存储值的副本并将它们传递给构建者的构造函数。这会导致 ReadOnlyPropertyException
当您尝试将它与不可变类一起使用时。
您可以使用此注释选择四种可能的 Builder 策略,其中我尝试过 DefaultStrategy
, ExternalStrategy
和 InitializerStrategy
.然而,所有这些都造成了问题。ExternalStrategy
看起来是四个中最有前途的,你可以找到一个基于它的 SSCCE 详细说明问题here .
示例中的源代码也包含在下面:
import groovy.transform.Immutable
import groovy.transform.builder.Builder as GBuilder
import groovy.transform.builder.ExternalStrategy
/*
* Uncommenting the below causes a failure:
* 'groovy.lang.ReadOnlyPropertyException: Cannot set readonly property: value for class: Value'
*/
//@Immutable
class Value {
@GBuilder(forClass = Value, prefix = 'set', builderStrategy = ExternalStrategy)
static class Builder { }
int value
String toString() { "Value($value)" }
}
def builder = new Value.Builder()
println builder.setValue(1).build()
InitializerStrategy
而不是
ExternalStrategy
.
java.lang.IllegalAccessError: tried to access class com.github.tagc.semver.version.BaseVersion from class com.github.tagc.semver.version.BaseVersion$com.github.tagc.semver.version.BaseVersionInitializer
at java.lang.Class.getDeclaringClass(Class.java:1227)
at java.beans.MethodRef.set(MethodRef.java:46)
at java.beans.MethodDescriptor.setMethod(MethodDescriptor.java:117)
at java.beans.MethodDescriptor.<init>(MethodDescriptor.java:72)
at java.beans.MethodDescriptor.<init>(MethodDescriptor.java:56)
at java.beans.Introspector.getTargetMethodInfo(Introspector.java:1163)
at java.beans.Introspector.getBeanInfo(Introspector.java:426)
at java.beans.Introspector.getBeanInfo(Introspector.java:173)
at com.github.tagc.semver.version.VersionFactory.createBaseVersion(VersionFactory.groovy:34)
at com.github.tagc.semver.test.util.TestSetup.<clinit>(TestSetup.groovy:77)
at java.lang.Class.forName(Class.java:344)
at com.github.tagc.semver.version.SnapshotDecoratorSpec.#decoratedVersion should be considered equal to patch-bumped #releaseVersion snapshot(SnapshotDecoratorSpec.groovy:24)
java.lang.NoClassDefFoundError: Could not initialize class com.github.tagc.semver.test.util.TestSetup
at java.lang.Class.forName(Class.java:344)
at com.github.tagc.semver.version.SnapshotDecoratorSpec.#decoratedVersion should be considered equal to minor-bumped #releaseVersion snapshot(SnapshotDecoratorSpec.groovy:36)
BaseVersion
类如下:
/**
* A concrete, base implementation of {@link com.github.tagc.semver.version.Version Version}.
*
* @author davidfallah
* @since v0.1.0
*/
@Immutable
@Builder(prefix = 'set', builderStrategy = InitializerStrategy)
@PackageScope
final class BaseVersion implements Version {
// ...
/**
* The major category of this version.
*/
int major = 0
/**
* The minor category of this version.
*/
int minor = 0
/**
* The patch category of this version.
*/
int patch = 0
/**
* Whether this version is a release or snapshot version.
*/
boolean release = false
// ...
}
/**
* A factory for producing base and decorated {@code Version} objects.
*
* @author davidfallah
* @since v0.5.0
*/
class VersionFactory {
// ...
/**
* Returns an instance of {@link com.github.tagc.semver.version.BaseVersion BaseVersion} constructed
* with the given parameters.
*
* @param major the major category value of the version instance
* @param minor the minor category value of the version instance
* @param patch the patch category value of the version instance
* @param release the release setting of the version instance
* @return an instance of {@code BaseVersion}
*/
static BaseVersion createBaseVersion(int major, int minor, int patch, boolean release) {
return new BaseVersion(major, minor, patch, release)
}
/**
* Returns an instance of {@link com.github.tagc.semver.version.BaseVersion BaseVersion} constructed
* with the given parameters.
*
* @param m a map of parameter names and their corresponding values corresponding to the
* construction parameters of {@code BaseVersion}.
*
* @return an instance of {@code BaseVersion}
*/
static BaseVersion createBaseVersion(Map m) {
return new BaseVersion(m)
}
/**
* Returns an instance of {@link com.github.tagc.semver.version.BaseVersion BaseVersion} constructed
* with the given parameters.
*
* @param l a list of parameter values corresponding to the construction parameters of {@code BaseVersion}.
*
* @return an instance of {@code BaseVersion}
*/
static BaseVersion createBaseVersion(List l) {
return new BaseVersion(l)
}
/**
* Returns a builder for {@link com.github.tagc.semver.version.BaseVersion BaseVersion} to specify
* the construction parameters for the {@code BaseVersion} incrementally.
*
* @return an instance of {@code BaseVersion.Builder}
*/
static Object createBaseVersionBuilder() {
return BaseVersion.builder()
}
// ...
}
Version
的测试规范类对象:
/**
* Test specification for {@link com.github.tagc.semver.version.Version Version}.
*
* @author davidfallah
* @since 0.1.0
*/
@Unroll
class VersionSpec extends Specification {
static exampleVersions = [
VersionFactory.createBaseVersion(major:1, minor:2, patch:3),
VersionFactory.createBaseVersion(major:0, minor:0, patch:0),
VersionFactory.createBaseVersion(major:5, minor:4, patch:3),
VersionFactory.createBaseVersion(major:1, minor:16, patch:2),
VersionFactory.createBaseVersion(major:4, minor:5, patch:8),
]
// ...
}
BaseVersion
实例的类失败的,例如
TestSetup
.
最佳答案
你那里的代码失败了,因为那里选择的策略基本上是:
def v = new Value().with{ setValue(1); return it }
@Immutable
上完成对象。
InitializerStrategy
,可以明确应对
@Immutable
.
You can use the InitializerStrategy in conjunction with @Canonical and @Immutable. If your @Builder annotation doesn’t have explicit includes or excludes annotation attributes but your @Canonical annotation does, the ones from @Canonical will be re-used for @Builder.
import groovy.transform.*
import groovy.transform.builder.*
@Immutable
@ToString
@Builder(prefix='set', builderStrategy=InitializerStrategy)
class Value {
int value
}
def builder = Value.createInitializer().setValue(1)
assert new Value(builder).toString()=='Value(1)'
@TypeChecked
new Value(vlaue: 666)
将产生一个错误并留下参数(对于具有多个属性的类)将留下它们
null
.
关于groovy - 有没有办法让 @Builder 注释适用于不可变类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28385275/
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
在现代 IDE 中,有一个键盘快捷键可以通过键入文件名称来打开文件,而无需将手放在鼠标上。例如: Eclipse:Cmd|Ctrl + Shift + R -> 打开资源 IntelliJ:Cmd|C
有什么东西会等待事件发生(我正在等待的是 WebBrowser.DocumentCompleted),然后执行代码吗?像这样: If (WebBrowser.DocumentCompleted) 不会
我使用 PHP Minify,它很棒。但我的问题是,是否有任何 PHP 插件或其他东西可以自动检测 javascript/css 代码并自动缩小它?谢谢。 最佳答案 Javascript 压缩器? 看
有没有一种语言,类似什么CoffeeScript是JavaScript,编译成windows batch|cmd|command line的语言? 我指的cmd版本是基于NT的,尤其是XP sp3及以
我知道我可以 ,但是,我真的宁愿有一个任务,我可以从任何可以使用所有(或至少大部分)属性的操作系统调用 copy ,但这并没有消除 unix 上的权限。 我想知道是否已经有解决方案,或者我必须自己编
我正在使用 Vuejs(不使用 jQuery)开发一个项目,该项目需要像 jvectormap 这样的 map 但正如我所说,我没有使用 jQuery,那么是否有任何其他库可以在不使用 jQuery
想要进行一个简单的民意调查,甚至不需要基于 cookie,我不在乎投了多少票。有没有类似的插件或者简单的东西? 最佳答案 这是一个有用的教程 - 让我知道它是否适合您 using jQuery to
已结束。此问题正在寻求书籍、工具、软件库等的推荐。它不满足Stack Overflow guidelines 。目前不接受答案。 我们不允许提出寻求书籍、工具、软件库等推荐的问题。您可以编辑问题,以便
就目前情况而言,这个问题不太适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、民意调查或扩展讨论。如果您觉得这个问题可以改进并可能重新开放,visit
var FileBuff: TBytes; Pattern: TBytes; begin FileBuff := filetobytes(filename); Result := Co
我想要一个 vqmod xml 文件来添加一次上传多个图像的功能。身边有这样的事吗? 编辑:Opencart版本:2.1.0.1 最佳答案 最后我写了一个xml来添加到opencart 2.1.0.1
所以考虑这样的函数: public void setTemperature(double newTemperatureValue, TemperatureUnit unit) 其中Temperatur
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我是 ggplot2 的新手,一直在尝试找到一个全面的美学列表。我想我理解它们的目的,但很难知道哪些可以在各种情况下使用(主要是几何图形?)。 Hadley 的网站偶尔会在各个几何图形的页面上列出可用
就目前情况而言,这个问题不太适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、民意调查或扩展讨论。如果您觉得这个问题可以改进并可能重新开放,visit
是否有任何 PHP 函数可以将整数转换为十万和千万? 900800 -> 9,00,800 500800 -> 5,00,800 最佳答案 由于您已在问题标签中添加了 Yii,因此您可以按照 Yii
使用 Clojure 一段时间后,我积累了一些关于它的惰性的知识。我知道诸如map之类的常用API是否是惰性的。然而,当我开始使用一个不熟悉的API(例如with-open)时,我仍然感到怀疑。 是否
我的项目需要一个像 AvalonDock 这样的对接系统,但它的最后一次更新似乎是在 2013 年 6 月。是否有更多...积极开发的东西可以代替它? 最佳答案 AvalonDock 实际上相当成熟并
我正在寻找一个可以逆转 clojure 打嗝的函数 所以 turns into [:html] 等等 根据@kotarak的回答,这现在对我有用: (use 'net.cgrand.enliv
我是一名优秀的程序员,十分优秀!