Groovy里面闭包中变量符号的查找与变量定义的限制
1 class a { 2 def v1 = "v1 in a" 3 static def v2 = "v2 in a" 4 def v4 = "v4 in a" 5 def v5 = "v5 in a" 6 def va = "va in a" 7 def b() { 8 def v1 = "v1 in a.b()" 9 def v2 = "v2 in a.b()" 10 def v4 = "v4 in a.b()" 11 def g = { 12 def v0 = "v0 in closure g" 13 def h = { 14 //function b里面已经定义v4 = "v4 in a.b()"所以下面这行 15 //报错:The current scope already contains a variable of the name v4 16 //def v4 = "v4 in closure h" 17 } 18 } 19 def c = { 20 //下面的这行代码报错:The current scope already contains a variable of the name v1 21 //def v1 = "v1 in closure c" 22 println v1 23 println owner 24 println this 25 //下面这行定义v5变量正常,输出的结果也是:v5 in closure c 26 def v5 = "v5 in closure c" 27 println v5//v4 28 println va 29 } 30 println "***" + c.toString() + "***" 31 c() 32 33 return "b func" 34 } 35 36 def d = { 37 println v1; 38 println v2; 39 println v4; 40 def v5 = "v5 in closure d" 41 println v5 42 } 43 44 def e = { 45 def v1 = "v1 in closure e" 46 def f = { 47 //下面这行代码报错:The current scope already contains a variable of the name v1 48 //def v1 = "v1 in closure f" 49 println v1 50 51 //下面这行就没错,因为闭包e的v2是在后面定义的 52 def v2 = "v2 in closure f" 53 54 //下面这行报错,v3在f里面不可见 55 //println v3 56 57 def vf = "vf in closure f" 58 } 59 f() 60 def v2 = "v2 in closure e" 61 def v3 = "v3 in closure e" 62 63 //在闭包e里面vf不可见 64 //println vf 65 } 66 } 67 def test(x) { 68 println "func test start --- x:" + x 69 def v1 = 1000 70 def v2 = 2000 71 def v3 = 3000 72 73 x() 74 println "func test--- end:" 75 } 76 test(new a().d) 77 println "--------------" 78 //println new a().v4 79 println new a().b() 80 new a().e() 81 82 83 /* 84 通过上面的测试代码可以看出: 85 1.在闭包a里面定义的闭包b,那么b中定义的变量不能和和闭包a里面定义的变量名字相同. 86 2.在函数a里面定义的闭包b,那么b中定义的变量不能和和函数a里面定义的变量名字相同. 87 3.由此也可以推导出:在函数a里面定义闭包b,在闭包b里面定义闭包c,那么c中定义 88 的变量也不能和函数a中定义的变量名字相同,对于任意多层闭包嵌套也是如此 89 在闭包里面的符号查找方面: 90 首先在闭包里面查找,如果闭包里面没有定义,则有两种情况(假设delegate策略是Closure.OWNER_FIRST,其它策略是一样的): 91 1.如果这个闭包的外层是函数,则现在函数里面查找,如果函数里面也没有定义,则进入delegate策略即在owner里面查找, 92 如果owner里面没有,则在delegate里面查找,ruguo delegate里面没有就报错 93 2.如果这个闭包没外层不是函数,则直接进入delegate策略即在owner里面查找,如果owner里面没有,则在delegate里面查找 94 如果delegate里面没有就报错. 95 96 */