- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
有人可以向我解释为什么在声明中使用initVars('c')
时,在closure2中@Field
无法修改引用的对象吗?
import groovy.transform.Field;
@Field def lines4 = "a";
void initVars(String pref){
println('init:'+lines4+' '+pref) //*3.init:a b *7.init:b c
lines4 = pref;
}
println("closure1") ///1. closure1
1.times {
println(lines4) ///2. a
initVars('b') ///3. init:a b
lines4 += 'p1'
println(lines4) ///4. bp1
}
println("closure2") ///5. closure2
1.times {
println(lines4) ///6. bp1
initVars('c') ///7. init:b c
println(lines4) ///8. bp1 Why not c
lines4 += 'q1'
println(lines4) ///9. bp1q1 Why not cq1
}
C:\projects\ATT>groovy test.groovy
1. closure1
2. a
3. init:a b
4. bp1
5. closure2
6. bp1
7. init:b c
8. bp1
9. bp1q1
@Field
和
def
,而在脚本作用域中只有
lines4 = "a"
。这对我来说似乎很正常。
C:\projects\ATT>groovy test.groovy
1. closure1
2. a
3. init:a
4. bp1
5. closure2
6. bp1
7. init:bp1
8. c
9. cq1
最佳答案
在脚本变量上使用@Field
批注会将此变量的范围从本地变量更改为Script
类1:
变量注释,用于将脚本内变量的范围从脚本的run方法内更改为脚本的类级别。
带注释的变量将成为脚本类的私有字段。字段的类型将与变量的类型相同。用法示例:
import groovy.transform.Field
@Field List awe = [1, 2, 3]
def awesum() { awe.sum() }
assert awesum() == 6
groovy.lang.Script
类,并且脚本主体在
Script.run()
方法内部执行。 Groovy使用
Binding
对象将变量传递给此脚本。当您将本地脚本变量的范围更改为类级别时,此变量没有绑定传递给闭包,因为
binding
对象
仅包含本地范围的变量。比较我制作的这两个屏幕截图。第一个显示了当我们第一次调用
binding
时
initVars(String pref)
对象的外观,而
lines4
是本地脚本变量:
lines4
是
@Field def lines4
变量:
lines4
对象中没有
binding
变量的绑定,但是有一个名为
lines4
的类字段,而该绑定在所附的第一个屏幕快照中。
lines4 += 'p1'
lines4
的本地绑定,并使用
this.lines4
值的当前值初始化它。这是因为
Script.getProperty(String property)
是通过以下方式实现的:
public Object getProperty(String property) {
try {
return binding.getVariable(property);
} catch (MissingPropertyException e) {
return super.getProperty(property);
}
}
getProperty(name)
实现-在我们的例子中,它只是返回类属性值。此时,
this.lines4
等于
b
,这是返回的值。
initVars(String pref)
方法访问类字段,因此在调用它时,它始终会覆盖
Script.lines4
属性。但是当你打电话
lines4 += 'q1'
lines4
已经存在,其值是
bp1
-该值在第一个闭包调用中关联。这就是为什么在调用
c
之后看不到
initVars('c')
的原因。希望对您有所帮助。
binding
如何在脚本中工作解释
Compiled from "script_with_closures.groovy"
public class script_with_closures extends groovy.lang.Script {
java.lang.Object lines4;
public static transient boolean __$stMC;
public script_with_closures();
public script_with_closures(groovy.lang.Binding);
public static void main(java.lang.String...);
public java.lang.Object run();
public void initVars(java.lang.String);
protected groovy.lang.MetaClass $getStaticMetaClass();
}
@Field def lines4
编译为一个类字段java.lang.Object lines4;
void initVars(String pref)
方法被编译为public void initVars(java.lang.String);
类方法。 lines4
和
initVars
方法)都内联到
public java.lang.Objectrun()
方法。
initVars
始终访问类字段
lines4
,因为它可以直接访问此字段。将这个方法反编译为字节码可以看到以下内容:
public void initVars(java.lang.String);
Code:
0: invokestatic #19 // Method $getCallSiteArray:()[Lorg/codehaus/groovy/runtime/callsite/CallSite;
3: astore_2
4: aload_2
5: ldc #77 // int 5
7: aaload
8: aload_0
9: aload_2
10: ldc #78 // int 6
12: aaload
13: aload_2
14: ldc #79 // int 7
16: aaload
17: aload_2
18: ldc #80 // int 8
20: aaload
21: ldc #82 // String init:
23: aload_0
24: getfield #23 // Field lines4:Ljava/lang/Object;
27: invokeinterface #67, 3 // InterfaceMethod org/codehaus/groovy/runtime/callsite/CallSite.call:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
32: ldc #84 // String
34: invokeinterface #67, 3 // InterfaceMethod org/codehaus/groovy/runtime/callsite/CallSite.call:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
39: aload_1
40: invokeinterface #67, 3 // InterfaceMethod org/codehaus/groovy/runtime/callsite/CallSite.call:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
45: invokeinterface #52, 3 // InterfaceMethod org/codehaus/groovy/runtime/callsite/CallSite.callCurrent:(Lgroovy/lang/GroovyObject;Ljava/lang/Object;)Ljava/lang/Object;
50: pop
51: aload_1
52: astore_3
53: aload_3
54: aload_0
55: swap
56: putfield #23 // Field lines4:Ljava/lang/Object;
59: aload_3
60: pop
61: return
delegate
字段设置为正在执行的脚本对象。我们知道它扩展了
groovy.lang.Script
类-使用
binding
private field来存储脚本运行时中可用的所有绑定(变量)的类。这很重要,因为
groovy.lang.Script
类覆盖:
public Object getProperty(String property)
public void setProperty(String property, Object newValue)
binding
查找和存储脚本运行时中使用的变量。只要您读取本地脚本变量,就可以调用
getProperty
,而只要您为脚本本地变量分配值,就可以调用
setProperty
。这就是为什么代码如下:
lines4 += 'p1'
getProperty -> value + 'p1' -> setProperty
lines4
最终会从父类返回一个值(如果未找到绑定,则会发生这种情况,然后
GroovyObjectSupport.getProperty(name)
is called会返回给定名称的类属性的值)。当闭包为
lines4
变量分配值时,将创建绑定。并且由于两个闭包共享相同的
binding
对象(它们使用委托给同一实例),因此当第二个闭包读取或写入
line4
变量时,它将使用先前创建的绑定。
initVars
不会修改绑定,因为正如我之前所展示的,它直接访问类字段。
关于groovy - 带有@Field批注的Groovy 2.4变量范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46579944/
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 5 年前。 Improve
我有一个 mysql 表,其中包含一个名为“id”、“name”和“number”的字段。 每一行的字段'number',都有一个数字。 id name number 1 test 30
我需要获得两个字段之间的最大和最小值。我将 JPA 2.1 与 EclipsLink 结合使用。 这是我的简化查询: SELECT GREATEST(c.min, mc.max), LEAST(c.m
我想知道是否可以询问具有相同字段名称的多个表,并且只写入一次询问的值。可能是为了避免裁员。 例如: SELECT * FROM table WHERE Table1.Status AND Ta
我想知道如何以负增量更新字段,但如果新值小于 1,则删除该行? 是否可以在 case 或 if/else block 中放置和更新语句? 目前我正在执行一个 select 语句来获取当前值,然后使用
嗨,我一直在寻找 secnhatouch 字段的 readOnly 属性,但没有找到它......有人可以帮助我解决这个问题吗 { xtype: 'textfield
SQL Server 2005 报告服务。 我想在报告文本框中使用以下内容: =IIF(IsNothing(Fields!Certification.Value), "", "Certs: "
考虑下表: un_id avl_id avl_date avl_status 1738 6377398 2011-03-10 unavailable 1738 6377399
鉴于集合将包含 50 多万份文档,每个文档都有最大数量的字段(如选项 a 所示)处理可能为空/稀疏的字段的最佳实践是什么? a)将每个具有相同字段和空字段的文档保存为 null 是否更好? { "
尝试开始使用 apioto http://apiato.io/A.getting-started/installation/ 如果我尝试测试 http://api.apiato.dev/registe
我在教程中找不到这两个指令之间的区别。 th:field="${something}"和 th:field="*{something}" 谁能告诉我一些例子? 最佳答案 Reference site
在 MongoDb 中 - 如果我的字段并不总是包含值 - 更好的做法是:在所有记录中保留相同的字段,即使有时这些字段为空或根本不创建这些字段? 10 倍! 最佳答案 字段会占用键的磁盘空间,即使没有
如何使用 factory-boy 定义依赖于其他字段的字段? 例如,我想定义一个 email这取决于 first name和 last name的 User . 我尝试使用 post_generati
嘿嘿, 我遇到了以下问题:我尝试阻止用户为“用户名”和“电子邮件”字段选择相同的值。我正在使用 jquery 表单验证插件 (http://bassistance.de/jquery-plugins/
在性能方面,哪个更适合使用? ...关于可读性/可理解性? ...关于公认的标准? SELECT * FROM Wherever WHERE Greeting IN ('hello', 'hi', '
我想知道使用 this 和 super 访问父类字段的区别。 我们有以下名为 ListItem 的抽象类,它扩展了 Node 类。 public abstract class ListItem {
假设 this 是一个指针,(2) 和 (3) 行如何在下面的 C++ 类中编译,所以应该需要 -> 符号来访问字段(如 (1) 行所示)? ( Source ) #include #include
我想更好地理解通过单独使用 this.field 和 field 来引用类字段有什么区别 this.integerField = 5; 和 integerField = 5; 最佳答案 this 关键
问题:我有一张库存表,还有一张列出正在拍卖的元素的表格。我想要一个别名字段(“isAuction”)来表示具有库存库存编号的项目是否存在于拍卖项目表中。 我写了以下查询: SELECT FROM in
如果我将包含多个字段的文档添加到 Elasticsearch 索引,当我在 Kibana 中查看它时,我每次都会得到相同的字段两次。其中之一将被称为 some_field 另一个将被调用 some_f
我是一名优秀的程序员,十分优秀!