Groovy 基础知识

1,808 阅读5分钟
原文链接: www.jianshu.com

在学习gralde的时候,经常会有一些语法不知如何操作,这时候就需要一些groovy的基础知识了。

基本语法

Groovy注释标记和Java一样,支持//或者/**/
Groovy语句可以不用分号结尾。
Groovy中支持动态类型,即定义变量的时候可以不指定其类型。Groovy中,变量定义可以使用关键字def。注意,虽然def不是必须的,但是为了代码清晰,建议还是使用def关键字:

def variable1 = 1   //可以不使用分号结尾  
def varable2 = "友盟分享"  
def  int x = 1  //变量定义时,也可以直接指定类型

函数定义时,参数的类型也可以不指定。比如 :

String testFunction(arg1,arg2){  //无需指定参数类型  
  ...  
}

除了变量定义可以不指定类型外,Groovy中函数的返回值也可以是无类型的。比如:

def  nonReturnTypeFunc(){  
    xxxxxx   //最后一行代码的执行结果就是本函数的返回值  
} 
//如果指定了函数返回类型,则可不必加def关键字来定义函数  
String getString(){  
   return"umeng share"  
}

Groovy对字符串支持相当强大,充分吸收了一些脚本语言的优点:
单引号''中的内容严格对应Java中的String,不对$符号进行转义

defsingleQuote='I am $ dolloar'  //输出就是I am $ dolloar

双引号""的内容则和脚本语言的处理有点像,如果字符中有$号的话,则它会$表达式先求值。

def aaa = "aaa" //输出aaa
def x = 1  
def result = "I am $x person" //输出I am 1 person

三个引号'''xxx'''中的字符串支持随意换行 比如

   defmultieLines = ''' begin  
     line  1  
     line  2  
     end '''

Groovy中函数调用的时候还可以不加括号:

println("test") 
println"test"

Groovy中的特殊数据类型

基本数据类型

作为动态语言,Groovy世界中的所有事物都是对象。所以,int,boolean这些Java中的基本数据类型,在Groovy代码中其实对应的是它们的包装数据类型。比如int对应为Integer,boolean对应为Boolean。

容器类

Groovy中的容器类很简单,就三种:
List:链表,其底层对应Java中的List接口,一般用ArrayList作为真正的实现类。
Map:键-值表,其底层对应Java中的LinkedHashMap。
Range:范围,它其实是List的一种拓展。
下面会举一些例子:
List

def aList = [5,'string',true] //List由[]定义,其元素可以是任何对象  
变量存取:可以直接通过索引存取,而且不用担心索引越界。如果索引超过当前链表长度,List会自动  
往该索引添加元素  
assert aList[1] == 'string'  
assert aList[5] == null //第6个元素为空  
aList[100] = 100 //设置第101个元素的值为10  
assert aList[100] == 100  
那么,aList到现在为止有多少个元素呢?  
println aList.size  ===>结果是101

Map

def aMap = ['key1':'value1','key2':true]  
/*Map由[:]定义,注意其中的冒号。冒号左边是key,右边是Value。key必须是字符串,value可以是任何对象。另外,key可以用''或""包起来,也可以不用引号包起来。比如  */
def aNewMap = [key1:"value",key2:true]//其中的key1和key2默认被  
处理成字符串"key1""key2"  
/*不过Key要是不使用引号包起来的话,也会带来一定混淆,比如  */
def key1="wowo"  
def aConfusedMap=[key1:"who am i?"]  
/*aConfuseMap中的key1到底是"key1"还是变量key1的值“wowo”?显然,答案是字符串"key1"。如果要是"wowo"的话,则aConfusedMap的定义必须设置成:  */
def aConfusedMap=[(key1):"who am i?"]  
/*Map中元素的存取更加方便,它支持多种方法:  */
println aMap.keyName  //  <==这种表达方法好像key就是aMap的一个成员变量一样  
println aMap['keyName']// <==这种表达方法更传统一点  
aMap.anotherkey = "i am map"  //<==为map添加新元素

Range

def aRange = 1..5 //<==Range类型的变量 由begin值+两个点+end值表示左边这个aRange包含1,2,3,4,5这5个值  如果不想包含最后一个元素,则  
def aRangeWithoutEnd = 1..<5  //<==包含1,2,3,4这4个元素  
println aRange.from  
println aRange.to

闭包

这个概念由一个例子看一下:

def aClosure = {//闭包是一段代码,所以需要用花括号括起来..  
    Stringparam1, int param2 ->  //这个箭头很关键。箭头前面是参数定义,箭头后面是代码  
    println"this is code" //这是代码,最后一句是返回值,  
   //也可以使用return,和Groovy中普通函数一样  
}

调用方法是:
闭包对象.call(参数) 或者更像函数指针调用的方法:
闭包对象(参数)

aClosure.call("this is string",100)  或者  
aClosure("this is string", 100)

文件操作

读取文件中的每一行

targetFile.eachLine{   
  String oneLine ->  
   println oneLine      
}

直接得到文件内容

targetFile.getBytes()

InputStream

def ism =  targetFile.newInputStream()  
//操作ism,最后记得关掉  
ism.close

 targetFile.withInputStream{ ism ->  
   //操作ism. 不用close。Groovy会自动替你close  
}

写文件

写文件与读取文件相似就不多说了,下面举个copy文件的例子:

def srcFile = new File(源文件名)  
def targetFile = new File(目标文件名)  
targetFile.withOutputStream{ os->  
  srcFile.withInputStream{ ins->  
      os << ins   //利用OutputStream的<<操作符重载,完成从inputstream到OutputStream的输出  
   }  
}

解析xml

gradle中解析xml最常用的就是解析AndroidManifest,下面举个例子,一起说一下:

<response version-api="2.0">  
       <value>  
           <books>  
               <book available="20" id="1">  
                   <title>Don Xijote</title>  
                   <author id="1">Manuel De Cervantes</author>  
               </book>  
               <book available="14" id="2">  
                   <title>Catcher in the Rye</title>  
                  <author id="2">JD Salinger</author>  
              </book>  
              <book available="13" id="3">  
                  <title>Alice in Wonderland</title>  
                  <author id="3">Lewis Carroll</author>  
              </book>  
              <book available="5" id="4">  
                  <title>Don Xijote</title>  
                  <author id="4">Manuel De Cervantes</author>  
              </book>  
           </books>  
      </value>  
   </response>

解析:

//第一步,创建XmlSlurper类  
def xparser = new XmlSlurper()  
def targetFile = new File("test.xml")  
//使用 GPathResult
GPathResult gpathResult =xparser.parse(targetFile)  

//开始玩test.xml。现在我要访问id=4的book元素。  
//下面这种搞法,gpathResult代表根元素response。通过e1.e2.e3这种  
//格式就能访问到各级子元素....  
def book4 = gpathResult.value.books.book[3]  
//得到book4的author元素  
def author = book4.author  
//再来获取元素的属性和textvalue  
assert author.text() == ' Manuel De Cervantes '  
获取属性更直观  
author.@id == '4' 或者 author['@id'] == '4'  
属性一般是字符串,可通过toInteger转换成整数  
author.@id.toInteger() == 4  
好了。GPath就说到这。再看个例子。我在使用Gradle的时候有个需求,就是获取AndroidManifest.xml版本号(versionName)。有了GPath,一行代码搞定,请看:  
def androidManifest = newXmlSlurper().parse("AndroidManifest.xml")  
println androidManifest['@android:versionName']  
或者  
println androidManifest.@'android:versionName'

*更多的开发知识,可以关注我的公众号:


Paste_Image.png