自己动手应用Groovy实现Gradle的DSL(二) Groovy的高级特性

霸气de小男生 提交于 2020-01-08 10:18:32

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

转载请注明出处: http://my.oschina.net/u/874727/blog/741610

如有问题可以加Q: 1025250620

非墨写的文章有时候是比较乱入的。只是觉得读者可能会需要这一部分的只是,所以临时插入。本篇文章主要是为了巩固一些Groovy的语法知识,主要参考资料来自于Groovy提供的官方文档。而这些所谓的高级特性,或许你在现在,将来都未必能用到,甚至登上你的平台。但是知道这些特性可以让你更加的理解Groovy这门语言,已经类似这门语言所要体现出来的语言范式。

言归正传:

1.map类型

map类型是Groovy很常用的类型,甚至我们在定义我们DSL的时候也经常用到,比如我们经常用到的

apply plugin:"com.android.application"

apply是Groovy的一个函数,而后面的参数就是一个Map类型的对象。一般map定义对象的方式是:

def m = [key:value]

但是如果key是引用的一个变量呢?Groovy有两种方式:

def key = "name"
def m = ["${key}":"david",age:19]
//or 
def m = [(key):"david",age:19]

2.类成员的引用

POGO对象通过Groovy所提供的语义和语法糖可以轻松的定义Property:

class MyObject {
    def getName() {
       "david"
    }
}
obj = new MyObject()
assert obj.name == "david"

由于默认范式obj.propertyName下都会被Groovy的get[PropertyName]方法拦截:

class MyObject {

   def name = "david"

   def getName() {
       "["+this.name+"]"
   }

}

obj = new MyObject()
assert obj.name == "[david]"

为了直接获取对象的属性避免被Groovy拦截需要在属性名字前面加入@符号

assert obj.@name == "david"

3.函数引用符号&

Groovy中可以通过&符号引用对象中的函数名,注意这里是函数名字,并没有说明是函数签名。

def doSomething(Integer int) {
   println "perform Integer"
}
def doSomething(String str) {
   println "perform String"
}

def funcObj = this.&doSomething
assert funcObj(1) == "perform Integer"
assert funcObj("ab") == "perform String"

4.属性分割符号*

直接看代码吧:

users = [

new User(name:"david",age:19),

null,

new User(name:"Lily",age:20)

]
assert users.*name == ["david",null,"Lily"]

5.运算符重载——符号"[]"

直接看代码吧:

class User {
    long id
    String name
    def getAt(int i) {
       switch (i) {
         case 0: return id
         case 1: return name 
       }
    }
    def putAt(int i,obj) {
       switch (i) {
         case 0: id = obj
         case 1: name = obj
       }
    }
}
user = new User(id:100,name:"david")
assert user[1] == "david"
user[0] = 11
assert user.id == 11

6.运算符重载——符号"as"

as操作符需要复写对象中的asType(Class clazz)方法

class MyObject {
  def asType(Class clazz) {
    if (clazz == String) { return "abc"}
  }
}
obj = new MyObject()
String str = obj as String
assert str == "abc"
assert str intanceof String

没有构造器的类,可以指定为任意接口类型

class MyObj {
  def callback() {
    println "perform callback"
  }
}
obj = new MyObj()
interface Interface1 {
  def callback()
}
interface Interface2 {
  def callback()
}

i1 = obj as Interface1
i2 = obj as Interface2
i1.callback()
i2.callback()

可以通过as来将map对象转化为具体对象

class Person {
   def name
   def age
}

p = [name:"david",age:19] as Person
<=>
Person p = [name:"david",age:19]

7.运算符重载——符号"()"

class Person {

    def call(int x) { x + 100}

}

p = new Person()

assert p(1) == 101

8.Map类型参数的展开

如果你的参数是Map对象,那么可以将map中的参数进行展开

def func(Map map) {
 
 map.each {
  println it.key+"->"+it.name
 }

}

def m = [name:"david",age:19]
assert func(m) == func(name:"david",age:19)

9.class的mixin操作

delegate是Groovy中常见的模式,对于Class也不例外。

class A {
  def callMethodA() {println "call A"}
}
class B {
  def callMethodB() {println "call B"}
}
A.metaClass.mixin B
a = new A()
a.callMethodA()
a.callMethodB()
assert !(a instanceof B)

mixin操作可以让classA 扩展出B中的方法,实际上市产生一个动态代理类。并且如果AB类中存在方法冲突,那么根据Groovy的调用规则,会先调用B中的方法

10.科里化闭包

科里化闭包实际上就是给闭包指定默认参数

def testCurry = {int age,String name->println "$name is $age"}
//左侧赋值:

testCurry.curry(12)

assert testCurry("david") == "david is 12"

//右侧赋值:

testCurry.rcurry("lily")

assert testCurry(9) == "david is 9"

//索引赋值:

testCurry.ncurry(0,123)

assert testCurry("sanny") == "sanny is 123"

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!