为什么Gradle中implementation(project(':ToastLibrary'))不能写为implementation project ':ToastLibrary'
报错原因解析
核心逻辑:Groovy语法解析的优先级与歧义规则
Groovy允许省略方法调用的括号仅当参数列表无语法歧义、编译器可以明确识别参数边界,结合Gradle API的定义,各个写法的解析逻辑如下:
- Gradle 中
project()是接收项目路径字符串作为参数的方法,调用后返回DefaultProjectDependency类型的依赖对象;implementation是依赖配置方法,接收依赖对象作为参数。
两种正确写法的解析逻辑
implementation(project(':ToastLibrary'))
编译器可以明确识别调用顺序:先执行project(':ToastLibrary')得到依赖对象,再将该对象传入implementation方法,无歧义,运行正常。implementation project(':ToastLibrary')
仅省略了implementation方法的外层括号,编译器仍可识别project(':ToastLibrary')是带括号的完整方法调用,整体作为implementation的参数,无歧义,运行正常。
两种错误写法的解析逻辑
implementation project ':ToastLibrary'
同时省略了implementation和project两个方法的括号,编译器解析时触发歧义:按照Groovy的规则,属性访问优先级高于无括号的方法调用,编译器会先解析为implementation(project)得到DefaultProjectDependency对象,再将后续的:ToastLibrary识别为要访问该对象的同名属性,但该对象不存在此属性,因此抛出对应错误。implementation(project ':ToastLibrary')
仅给implementation的参数加了括号,但project方法的参数未加括号,编译器解析括号内内容时,仍会将project ':ToastLibrary'识别为「访问project对象的:ToastLibrary属性」,而非调用project方法传入参数,因此同样找不到对应属性报错。
补充说明
如果project是独立调用,单独写def dep = project ':ToastLibrary'可以正常执行,不会触发歧义,因为此时没有嵌套方法调用的场景,编译器可以明确识别参数边界。
内容的提问来源于stack exchange,提问作者zhangjin
相关产品推荐
相关产品推荐

