Groovy介紹

參考:
深入理解Android之Gradle
Groovy與Java的區(qū)別
Groovy語法
Groovy基礎(chǔ)——Closure(閉包)詳解

def varAndMethod() {
    def a = 1  //不顯式聲明變量類型
    a = "abc"  //運行時改變類型
    println a  //結(jié)尾無需 茉唉;
    a = 4      //最后一行作為返回值
}
def ret = varAndMethod()
println ret    //輸出4

Groovy是一種動態(tài)語言。對自己的定義就是:Groovy是在 java平臺上的佩憾、 具有像Python掩蛤, Ruby 和 Smalltalk 語言特性的靈活動態(tài)語言枉昏。
除了語言和Java相通外,Groovy有時候又像一種腳本語言揍鸟。

下面我們將介紹Groovy兄裂。由于此文的主要目的是Gradle,所以我們不會過多討論Groovy中細枝末節(jié)的東西蜈亩,而是把知識點集中在以后和Gradle打交道時一些常用的地方上懦窘。

一 前提知識

1.Groovy注釋標記和Java一樣,支持//或者/**/
2.Groovy語句可以不用分號結(jié)尾稚配。Groovy為了盡量減少代碼的輸入畅涂,確實煞費苦心
3.Groovy中支持動態(tài)類型,即定義變量的時候可以不指定其類型道川。
4.Groovy中午衰,變量定義可以使用關(guān)鍵字def。注意冒萄,雖然def不是必須的臊岸,但是為了代碼清晰,
  建議還是使用def關(guān)鍵字
  def i = 1       //可以不使用分號結(jié)尾
  def ss = "I ama person"
  def  int x = 1  //變量定義時尊流,也可以直接指定類型
5.函數(shù)定義時帅戒,參數(shù)的類型也可以不指定。比如
  String testFunction(arg1,arg2){ //無需指定參數(shù)類型
    ...
  }  
6.除了變量定義可以不指定類型外崖技,Groovy中函數(shù)的返回值也可以是無類型的逻住。比如:
  //無類型的函數(shù)定義钟哥,必須使用def關(guān)鍵字
  def  nonReturnTypeFunc(){
      last_line   //最后一行代碼的執(zhí)行結(jié)果就是本函數(shù)的返回值
  }
  //如果指定了函數(shù)返回類型,則可不必加def關(guān)鍵字來定義函數(shù)
  String getString(){
     return"I am a string"
  }
7.函數(shù)返回值:Groovy的函數(shù)里瞎访,可以不使用returnxxx來設(shè)置xxx為函數(shù)返回值腻贰。
  如果不使用return語句的話,則函數(shù)里最后一句代碼的執(zhí)行結(jié)果被設(shè)置成返回值扒秸。比如
  //下面這個函數(shù)的返回值是字符串"getSomething return value"
  def getSomething(){
       "I am a return value" //最后一行代碼播演,返回類型為String
  }
  注意,如果函數(shù)定義時候指明了返回值類型的話伴奥,函數(shù)中則必須返回正確的數(shù)據(jù)類型写烤。
8.最后,除了每行代碼不用加分號外渔伯,Groovy中函數(shù)調(diào)用的時候還可以不加括號顶霞。比如:
  println("test") ---> println"test"
  注意,雖然寫代碼的時候锣吼,對于函數(shù)調(diào)用可以不帶括號选浑,但是Groovy經(jīng)常把屬性和函數(shù)混淆。比如
  def method(){
    "hello"
  }
  method  //如果不加括號的話玄叠,Groovy會誤認為method是一個變量古徒。找不到就會報錯:
  所以調(diào)用函數(shù)最好帶上括號,也好理解一些读恃,如果這個函數(shù)是Groovy API
  或者Gradle API中比較常用的隧膘,比如println,就可以不帶括號寺惫。

Groovy中的字符串

Groovy對字符串支持相當(dāng)強大疹吃,充分吸收了一些腳本語言的優(yōu)點:
1  單引號''中的內(nèi)容嚴格對應(yīng)Java中的String,不對$符號進行轉(zhuǎn)義
   defsingleQuote='I am $ dolloar'  //輸出就是I am $ dolloar
2  雙引號""的內(nèi)容則和腳本語言的處理有點像西雀,如果字符中有$號的話萨驶,則它會$表達式先求值。
   def s1 = "I am one dollar" //輸出 I am one dollar
   def x = 1
   def s2 = "I am $x dolloar" //輸出I am 1 dolloar
3 三個引號'''xxx'''中的字符串支持隨意換行 比如
   defmultieLines = ''' begin
     line  1
     line  2
     end '''

二 Groovy中的數(shù)據(jù)類型

主要有3種:

  • 一個是Java中的基本數(shù)據(jù)類型艇肴。
  • 另外一個是Groovy中的容器類腔呜。
  • 最后一個非常重要的是閉包。

基本數(shù)據(jù)類型

  • 作為動態(tài)語言再悼,Groovy世界中的所有事物都是對象核畴。所以,int冲九,boolean這些Java中的基本數(shù)據(jù)類型谤草,在Groovy代碼中其實對應(yīng)的是它們的包裝數(shù)據(jù)類型,比如int對應(yīng)為Integer,boolean對應(yīng)為Boolean,因此可以對變量直接調(diào)用方法:
def int x = 4
y = 3
assert x.plus(y) == 7

閉包

閉包,英文叫Closure咖刃,是Groovy中非常重要的一個數(shù)據(jù)類型或者說一種概念了泳炉。閉包的歷史來源憾筏,種種好處我就不說了嚎杨。我們直接看怎么使用它!

  1. 閉包氧腰,是一種數(shù)據(jù)類型枫浙,它代表了一段可執(zhí)行的代碼。其外形如下:
def aClosure = {  //閉包是一段代碼古拴,用花括號括起來..
    String param1, int param2 ->  //這個箭頭很關(guān)鍵箩帚。
                        //箭頭前面是參數(shù)定義,箭頭后面是代碼塊
    println"this is code" //這是代碼塊黄痪,最后一句是返回值紧帕,
                //也可以使用return,和Groovy中普通函數(shù)一樣
}

簡而言之桅打,Closure的定義格式是:

def xxx = {paramters -> code}  //或者  
def xxx = {無參數(shù)純code}  這種case不需要->符號

閉包定義好后是嗜,要調(diào)用它的方法就是:
--閉包對象.call(參數(shù)) 或者:
--閉包對象(參數(shù))

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

上面就是一個閉包的定義和使用。

  1. 在閉包中挺尾,還需要注意一點:
    如果閉包沒定義參數(shù)的話鹅搪,則隱含有一個參數(shù),這個參數(shù)名字叫it遭铺,和this的作用類似丽柿。it代表閉包的參數(shù)。比如:
def greeting = { "Hello, $it!" }
assert greeting('Patrick') == 'Hello, Patrick!'
等同于:
def greeting = { it -> "Hello, $it!"}
assert greeting('Patrick') == 'Hello, Patrick!'

但是魂挂,如果在閉包定義時甫题,采用下面這種寫法,則表示閉包沒有參數(shù)涂召!

def noParamClosure = { -> true }
這個時候坠非,我們就不能給noParamClosure傳參數(shù)了!
noParamClosure ("test")  <==報錯喔芹扭!
  1. 省略圓括號
    Groovy中麻顶,當(dāng)函數(shù)的最后一個參數(shù)是閉包的話,可以省略圓括號舱卡。
    閉包在Groovy中大量使用辅肾,比如很多類都定義了一些函數(shù),這些函數(shù)最后一個參數(shù)都是一個閉包轮锥。比如:
public static <T> List<T>each(List<T> self, Closure closure)
//上面這個函數(shù)表示針對List的每一個元素都會調(diào)用closure做一些處理矫钓。
//這里的closure,就有點回調(diào)函數(shù)的感覺。但是新娜,在使用這個each函數(shù)的時候赵辕,
//我們傳遞一個怎樣的Closure進去呢?比如:
def iamList = [1,2,3,4,5]  //定義一個List
iamList.each{ //調(diào)用它的each概龄,這段代碼的格式看不懂了吧还惠?each是個函數(shù),圓括號去哪了私杜?
      println it
}
上面代碼有兩個知識點:
    1) each函數(shù)調(diào)用的圓括號不見了蚕键!原來,Groovy中衰粹,當(dāng)函數(shù)的最后一個參數(shù)是閉包的話锣光,可以省略圓括號。比如
def testClosure(int a1,String b1, Closure closure){
      //dosomething
     closure() //調(diào)用閉包
}
那么調(diào)用的時候铝耻,就可以免括號誊爹!
testClosure (4, "test", {
      println"i am in closure"
} )  //括號可以不寫..

注意,這個特點非常關(guān)鍵瓢捉,因為以后在Gradle中經(jīng)常會出現(xiàn)圖7這樣的代碼:

閉包調(diào)用

經(jīng)常碰見這樣的沒有圓括號的代碼频丘。省略圓括號雖然使得代碼簡潔,但是卻使代碼很難理解泊柬,完整的代碼應(yīng)該按下面這種寫法:

 doLast({
   println'Hello world!'
 })

有了圓括號椎镣,你會知道 doLast只是把一個Closure對象傳了進去。很明顯兽赁,它不代表這段腳本解析到doLast的時候就會調(diào)用println ‘Hello world!’ 状答。但是把圓括號去掉后,就感覺好像println ‘Hello world!’立即就會被調(diào)用一樣刀崖!

容器類

Groovy中的容器類很簡單惊科,就三種:

  • List:鏈表,其底層對應(yīng)Java中的List接口亮钦,一般用ArrayList作為真正的實現(xiàn)類馆截。
  • Map:鍵-值表,其底層對應(yīng)Java中的LinkedHashMap蜂莉。
  • Range:范圍蜡娶,它其實是List的一種拓展。

對容器而言映穗,我們最重要的是了解它們的用法窖张。下面是一些簡單的例子:

  • List類
變量定義:List變量由[]定義,比如
def aList = [5,'string',true] //List由[]定義蚁滋,其元素可以是任何對象
//變量存人藿印:可以直接通過索引存取赘淮,而且不用擔(dān)心索引越界。
//如果索引超過當(dāng)前鏈表長度睦霎,List會自動
往該索引添加元素
assert aList[1] == 'string'
assert aList[5] == null //第6個元素為空
aList[100] = 100 //設(shè)置第101個元素的值為10
assert aList[100] == 100
那么梢卸,aList到現(xiàn)在為止有多少個元素呢?
println aList.size  ===>結(jié)果是101
  • Map類
容器變量定義
1.變量定義:Map變量由[:]定義副女,比如
      def aMap = ['key1':'value1','key2':true]
      注意其中的冒號蛤高。冒號左邊是key,右邊是Value肮塞。
2.key必須是字符串襟齿,value可以是任何對象。
      另外枕赵,key可以用''或""包起來,也可以不用引號包起來位隶。比如
      def aNewMap = [key1:"value",key2:true]
      其中的key1和key2默認被處理成字符串"key1"和"key2"拷窜,
      但最好是用""引起來,避免引起混淆涧黄。比如:

      def key1="wowo"
      def aConfusedMap=[key1:"who am i?"]
      aConfuseMap中的key1到底是"key1"還是變量key1的值“wow”篮昧?
      顯然,答案是字符串"key1"笋妥。如果要是"wowo"的話懊昨,則aConfusedMap的定義必須設(shè)置成:
      def aConfusedMap=[(key1):"who am i?"]
3.Map中元素的存取更加方便,它支持多種方法:
      println aMap.keyName    <==這種表達方法好像key就是aMap的一個成員變量一樣
      println aMap['keyName'] <==這種表達方法更傳統(tǒng)一點
      aMap.anotherkey = "i am map"  <==為map添加新元素
  • Range類
Range是Groovy對List的一種拓展春宣,變量定義和大體的使用方法如下:
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

多嘴一句,文檔中并沒有說明Range有from和to這兩個屬性月帝,但是卻有g(shù)etFrom和getTo這兩個函數(shù)躏惋。根據(jù)Groovy的原則,如果一個類中有名為xxyyzz這樣的屬性(其實就是成員變量)嚷辅,Groovy會自動為它添加getXxyyzz和setXxyyzz兩個函數(shù)簿姨,用于獲取和設(shè)置xxyyzz屬性值。
注意簸搞,get和set后第一個字母是大寫的
所以扁位,當(dāng)你看到Range中有g(shù)etFrom和getTo這兩個函數(shù)時候,就得知道潛規(guī)則下趁俊,Range有from和to這兩個屬性域仇。當(dāng)然,由于它們不可以被外界設(shè)置则酝,所以沒有公開setFrom和setTo函數(shù)殉簸。

三 變量的作用域

def x = 1 <==注意闰集,這個x有def(或者指明類型,比如 int x = 1)
def printx(){
   println x
}

printx() <==報錯般卑,說x找不到武鲁,生成的java代碼如下:

源碼
源碼

1.printx被定義成test類的成員函數(shù)
2.def x = 1,這句話是在run方法中創(chuàng)建的蝠检。所以沐鼠,x=1從代碼上看好像是在整個腳本中定義的,但實際上printx訪問不了它叹谁。printx是test成員函數(shù)饲梭,除非x也被定義成test的成員函數(shù),否則printx不能訪問它焰檩。

那么憔涉,如何使得printx能訪問x呢?很簡單析苫,定義的時候不要加類型和def兜叨。即:

x = 1 <==注意,去掉def和類型
def printx(){
   println x
}

現(xiàn)在生成的java代碼如下:

源碼

比較復(fù)雜衩侥,x也沒有被定義成test的成員變量国旷,而是在run的執(zhí)行過程中,將x作為一個屬性添加到test實例對象中了茫死。然后在printx中跪但,先獲取這個屬性。
注意峦萎,Groovy的文檔說 x = 1這種定義將使得x變成test的成員變量屡久,但從反編譯情況看,這是不對得…..
雖然printx可以訪問x變量了骨杂,但是別的腳本卻無法訪問x變量涂身。因為它不是test的成員變量。

那么如何才能定義成成員變量呢:

import groovy.transform.Field;   //必須要先import
@Field x = 1  <==在x前面加上@Field標注搓蚪,這樣蛤售,x就徹徹底底是test的成員變量了。

查看編譯后的test.class文件妒潭,得到:


源碼
源碼

四 文件操作

Groovy的I/O操作是在原有Java I/O操作上進行了更為簡單方便的封裝悴能,并且使用Closure來簡化代碼編寫。主要封裝了如下一些了類:


封裝類

java.io.File: http://docs.groovy-lang.org/latest/html/groovy-jdk/java/io/File.html
java.io.InputStream:http://docs.groovy-lang.org/latest/html/groovy-jdk/java/io/InputStream.html
java.io.OutputStream:http://docs.groovy-lang.org/latest/html/groovy-jdk/java/io/OutputStream.html
java.io.Reader:http://docs.groovy-lang.org/latest/html/groovy-jdk/java/io/Reader.html
java.io.Writer:http://docs.groovy-lang.org/latest/html/groovy-jdk/java/io/Writer.html
java.nio.file.Path:http://docs.groovy-lang.org/latest/html/groovy-jdk/java/nio/file/Path.html

讀文件
def targetFile = new File(文件名) <==File對象還是要創(chuàng)建的雳灾。
然后打開File的API看看Groovy定義的API:

讀該文件中的每一行的方法:eachLine的唯一參數(shù)是一個Closure漠酿。Closure的參數(shù)是文件每一行的內(nèi)容及行數(shù)
其內(nèi)部實現(xiàn)肯定是Groovy打開這個文件,然后讀取文件的一行谎亩,然后調(diào)用Closure…

 targetFile.eachLine{ 
   String oneLine,int lineNum ->
    println oneLine    
}  <==是不是令人發(fā)指炒嘲?宇姚?!

不用處理關(guān)閉流之類的夫凸,Groovy已經(jīng)幫處理了

直接得到文件內(nèi)容:
targetFile.getText() 或者
targetFile.getBytes() <==文件內(nèi)容一次性讀出

流操作

1. 直接操作inputStream
def ism =  targetFile.newInputStream()
//操作ism浑劳,最后記得關(guān)掉
ism.close

2. 使用閉包操作inputStream,以后在Gradle里會池舶瑁看到這種搞法
 targetFile.withInputStream{ ism ->
   ...//操作ism. 不用close魔熏。Groovy會自動替你close
}
//file.withInputStream方法參考API可知參數(shù)
//就一個Closure,回創(chuàng)建一個本文件的輸
//入流并作為參數(shù)傳遞給Closure
寫文件
def targetFile = new File(目標文件名)
targetFile.withOutputStream{ os->
  os.setBytes(內(nèi)容)
}

XML操作
除了I/O異常簡單之外,Groovy中的XML操作也極致得很鸽扁。Groovy中蒜绽,XML的解析提供了和XPath類似的方法,名為GPath桶现。這是一個類躲雅,提供相應(yīng)API。
GPath功能包括:給個例子好了巩那,來自Groovy官方文檔吏夯。

test.xml文件:
<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>

現(xiàn)在來看怎么玩轉(zhuǎn)GPath:

//第一步,創(chuàng)建XmlSlurper類
def xparser = new XmlSlurper()
def targetFile = new File("test.xml")
//轟轟的GPath出場
GPathResult gpathResult =xparser.parse(targetFile)
 
//開始玩test.xml〖春幔現(xiàn)在我要訪問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轉(zhuǎn)換成整數(shù)
author.@id.toInteger() == 4

好了战授。GPath就說到這页藻。再看個例子。我在使用Gradle的時候有個需求植兰,就是獲取AndroidManifest.xml版本號(versionName)份帐。有了GPath,一行代碼搞定楣导,請看:

def androidManifest = newXmlSlurper().parse("AndroidManifest.xml")
println androidManifest['@android:versionName']
或者
println androidManifest.@'android:versionName'

-> setting.gradle文件
def initXXX(){  
    println"initialize  ....."  
    ......//干一些special的私活....   
}  
//settings.gradle加載的時候废境,會執(zhí)行initMinshengGradleEnvironment  
initXXX()  
include 'youku' , 'alipay' , 'baidu'
apply from: rootProject.getRootDir().getAbsolutePath() + "/utils.gradle"
  Properties properties = new Properties()  
  File propertyFile = new File(rootDir.getAbsolutePath() +"/local.properties")  
   properties.load(propertyFile.newDataInputStream())  
    //gradle就是gradle對象。它默認是Settings和Project的成員變量筒繁∝迹可直接獲取  
   //ext前綴,表明操作的是外置屬性毡咏。api是一個新的屬性名驮宴。前面說過,只在  
   //第一次定義或者設(shè)置它的時候需要ext前綴  
    gradle.ext.api =properties.getProperty('sdk.api')  
     
    println gradle.api  //再次存取api的時候呕缭,就不需要ext前綴了  


//utils.gradle中定義了一個獲取AndroidManifests.xml的versionName的方法
def  getVersionNameAdvanced(){
?   //下面這行代碼中的project是誰堵泽?
   defxmlFile = project.file("AndroidManifest.xml")
   defrootManifest = new XmlSlurper().parse(xmlFile)
   return rootManifest['@android:versionName']  
}
//現(xiàn)在修己,想把這個方法輸出到各個Project碟贾。由于這個utils.gradle會被每一個Project Apply贷腕,所以
ext{   
    //除了ext.xxx=value這種定義方法外祸憋,還可以使用ext{}這種書寫方法泵殴。
    getVersionNameAdvanced = this.&getVersionNameAdvanced
 }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末夯接,一起剝皮案震驚了整個濱河市殴蹄,隨后出現(xiàn)的幾起案子吩屹,更是在濱河造成了極大的恐慌斋竞,老刑警劉巖钻蔑,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件啥刻,死亡現(xiàn)場離奇詭異,居然都是意外死亡咪笑,警方通過查閱死者的電腦和手機可帽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來窗怒,“玉大人映跟,你說我怎么就攤上這事⊙镄椋” “怎么了努隙?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長辜昵。 經(jīng)常有香客問我荸镊,道長,這世上最難降的妖魔是什么堪置? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任躬存,我火速辦了婚禮,結(jié)果婚禮上舀锨,老公的妹妹穿的比我還像新娘岭洲。我一直安慰自己,他們只是感情好坎匿,可當(dāng)我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布盾剩。 她就那樣靜靜地躺著,像睡著了一般碑诉。 火紅的嫁衣襯著肌膚如雪彪腔。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天进栽,我揣著相機與錄音德挣,去河邊找鬼。 笑死快毛,一個胖子當(dāng)著我的面吹牛格嗅,可吹牛的內(nèi)容都是我干的番挺。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼屯掖,長吁一口氣:“原來是場噩夢啊……” “哼玄柏!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起贴铜,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤粪摘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后绍坝,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體徘意,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年轩褐,在試婚紗的時候發(fā)現(xiàn)自己被綠了椎咧。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡把介,死狀恐怖勤讽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拗踢,我是刑警寧澤脚牍,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站巢墅,受9級特大地震影響莫矗,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜砂缩,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望三娩。 院中可真熱鬧庵芭,春花似錦、人聲如沸雀监。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽会前。三九已至,卻和暖如春瓦宜,著一層夾襖步出監(jiān)牢的瞬間蔚万,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工临庇, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留反璃,地道東北人昵慌。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像淮蜈,于是被迫代替她去往敵國和親斋攀。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容

  • Groovy :是一種動態(tài)語言梧田。 1:這種語言比較有特點淳蔼,它和 Java 一樣,也運行于 Java 虛擬機中裁眯。簡單...
    PeytonWu閱讀 1,545評論 0 1
  • 介紹 Gradle 是android studio帶的一款構(gòu)建工具鹉梨,方便、實用未状,一大堆的好話就不說了俯画。如果要熟練使...
    JeremyDai閱讀 456評論 0 0
  • 什么是 Groovy? 簡言之司草,Groovy是一種基于JVM(Java虛擬機)的敏捷動態(tài)開發(fā)語言艰垂。它是一種成熟的面...
    北緯26閱讀 4,118評論 0 14
  • 基于該網(wǎng)站深入理解groovy學(xué)習(xí),Android Studio使用gradle工具進行打包編譯的埋虹,而gradle...
    臥水萊藤閱讀 724評論 0 3
  • 2017年10月5日星期四 距離18考研 78天 就像回到小時暑假開學(xué)猜憎,想要逃跑。 2017年10月5日星期四 距...
    sy_yunyi閱讀 115評論 0 0