android studio 不能run_问:gradle 里 def 方法为什么不能引用 def 的变量?

点击蓝色小字关注!  关注一下你就不会有bug!

27f0e43e9b54f8e4d8432902de1e413d.png为什么引用不到

在 gradle 中,直接定义一个变量,再定义一个方法,在方法里里是不能引用到该变量的,但在一个闭包中就可以。
1def x = 1
2
3def fun() { println x }
4fun()
5
6android { println x }

如上图所示,fun 无法引用 x,会报错。但 android 闭包中的 x 却能打印出来。这是为什么呢?

1def x = 1
2
3def fun1() { println x }
4
5fun1()
6
7def fun2(Closure closure) { closure() }
8
9fun2 { println x }

运行上面的文件,会报错 Caught: groovy.lang.MissingPropertyException: No such property: x for class: MyGroovy。注释掉 fun1() 后,就可以正常运行。由于在工具栏上的配置中运行时没有生成 build 文件夹,我们手动执行下 compileGroovy 方法,在 app/build/classes/groovy/main 查看编译后的 MyGroovy.class。核心代码是这样的:

 1public Object run() {
2    Reference x = new Reference(1);
3    this.fun1();
4    class _run_closure1 extends Closure implements GeneratedClosure {
5    }
6    return var1[2].callCurrent(this, new _run_closure1(this, x));
7}
8
9public Object fun1() {
10    CallSite[] var1 = $getCallSiteArray();
11    return var1[3].callCurrent(this, var1[4].callGroovyObjectGetProperty(this));
12}
13
14public Object fun2(Closure closure) {
15    CallSite[] var2 = $getCallSiteArray();
16    return var2[5].call(closure);
17}

run() 方法就是 groovy 脚本执行的方法。可以看出,它先生成了一个 x 的引用,然后调用 fun1、fun2。

fun1 调用时,在它的内部执行了 callGroovyObjectGetProperty 方法,在获取 Groovy 对象的属性。也就是在属性中去寻找 x。

fun2 调用时,是将 x 直接传入了闭包的对象。

因为 x 并不是一个属性,只是一个临时变量,所以 fun1 获取不到,而 fun2 能获取到。

defbeddcc62a16a0d6fc759f6f1ee451.png怎么引用到

既然是因为属性中没有 x,那我们把 x 加入到属性中就可以了。看一下 gradle 中一个 project 的属性有哪些。一个 project 有 6 种属性的作用域:

  • Project 自己。

  • 这个 project 的附加属性(通过 ext 定义)。

  • 通过插件加入到 Project 的 extensions。

  • 通过插件加入到 Project 的 convention 属性。

  • 这个 project 里的 task。

  • 这个 project 的父 project,递归到根 project。从这里访问到的都是只读的。

所以,将 x 的定义放在 ext 中即可:

1ext { x = 1 } // 或者 ext.x = 1
2
3def fun() { println x }
4
5fun()

现在能正常打印出 x 的值。另外,使用 Script 的 binding 对象也可以实现属性中添加 x。

1binding.setVariable("x", 1)
2def fun() { println x }
3fun()
原文:https://blog.csdn.net/Gdeer/java/article/details/83106449 4381b61bd598d4b4e7b96e6976c3439d.gif▼往期精彩回顾▼线程池中线程是如何知道自己达到 keepAliveTime 时间,然后销毁的?线程池 keepAliveTime=0 时到底是什么含义???

407074d3964d793796fe9a6ce3d1f2f2.png

209ebea7d90823b5e266a9c4829a6792.png点击左下角阅读原文查看历史经典技术问题汇总,看完顺手走一波PYQ呀~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值