• Groovy基本语法


    官方文档

    注释(Comments)

    和Java一样,支持单行(使用//)、多行(/* */)和文档注释(使用/** */)。

    Shebang line

    UNIX系统支持一种特殊的单行注释叫作Shebang line,用于指明脚本的运行环境,这样就可以直接在终端中使用./xxx.groovy运行(当然,前提是文件得有可运行的权限),而不用像groovy xxx.groovy这样运行:

    #!/usr/bin/env groovy
    println "Hello from the shebang line"
    

    #号必须是文件的第一个字符。

    标识符(Identifiers)

    普通标识符

    以字母、美元符号$或下划线_开始,不能以数字开始。以下是可用的标识符:

    def name
    def item3
    def with_underscore
    def $dollarStart
    

    以下是不可用的标识符:

    def 3tier // 不能以数字开始
    def a+b   // "+"号是非法字符
    def a#b   // #号也不是可用的字符
    

    注意:在点号后,是可以使用关键字作为标识符的:

    foo.as
    foo.assert
    foo.break
    foo.case
    foo.catch
    

    引号标识符(Quoted identifiers)

    Groovy在点表达式(dotted expression)后面可以使用引号标识符,比如persion.name可以表示为persion.'name'persion."name"。而引号中可以包含普通标识符中不支持的字符,比如空格、中档线-这些:

    def map = [:]
    
    map."an identifier with a space and double quotes" = "ALLOWED"
    map.'with-dash-signs-and-single-quotes' = "ALLOWED"
    
    assert map."an identifier with a space and double quotes" == "ALLOWED"
    assert map.'with-dash-signs-and-single-quotes' == "ALLOWED"
    

    其实,Groovy支持多种字符串的字面量表达形式,这些都是可以出现在点号后面的:

    map.'single quote'
    map."double quote"
    map.'''triple single quote'''
    map."""triple double quote"""
    map./slashy string/
    map.$/dollar slashy string/$
    

    更方便的是,Groovy中的GString支持插值,也可以用在点号后面的:

    def firstname = "Homer"
    map."Simson-${firstname}" = "Homer Simson" // 会被插值成map."Simson-Homer"
    
    assert map.'Simson-Homer' == "Homer Simson"
    

    字符串

    在Groovy中字符串有两种类型,一种是Java原生的java.lang.String;另一种是groovy.lang.GString,又叫插值字符串(interpolated strings)。

    单引号字符串(Single quoted string)

    在Groovy中,使用单引号括住的字符串就是java.lang.String,不支持插值:

    def name = 'yjiyjgie'
    println name.class // class java.lang.String
    

    三单引号字符串(Triple single quoted string)

    使用三单引号括住字符串支持多行,也是java.lang.String实例,在第一个’‘’起始处加一个反斜杠可以在新一行开始文本:

    def strippedFirstNewline = '''line one
    line two
    line three
    '''
    // 可以写成下面这种形式,可读性更好
    def strippedFirstNewline = '''
    line one
    line two
    line three
    '''
    

    双引号字符串(Double quoted string)

    如果双引号括住的字符串中没有插值表达式(interpolated expression),那它就是java.lang.String;如是有插值表达式,那它就是groovy.lang.GString

    def normalStr = "yjiyjige" // 这是一个java.lang.String
    def interpolatedStr = "my name is ${normalStr}" // 这是一个groovy.lang.GString
    

    字符串插值(String interpolation)

    在Groovy所有的字符串字面量表示中,除了单引号字符串和三单引号字符串,其他形式都支持字符串插值。字符串插值,也即将占位表达式中的结果最终替换到字符串相应的位置中:

    def name = 'Guillaume' // a plain string
    def greeting = "Hello ${name}" // name变量的值会被替换进去
    
    assert greeting.toString() == 'Hello Guillaume'
    

    当使用点号表达式时,可以只用$代替${}

    def person = [name: 'Guillaume', age: 36]
    println "$person.name is $person.age years old"
    
    // 注意
    def number = 3.14
    println "$number.toString()" // 这里会报异常,因为相当于"${number.toString}()"
    println "${number.toString()}" // 这样就正常了
    

    插值占位符中还支持闭包,而闭包的一个好处是惰性求值(lazy evaluation):

    def number = 1
    def eagerGString = "value == ${number}" // 普通形式
    def lazyGString = "value == ${-> number}" // 这是一个闭包
    
    println eagerGString == "value == 1"
    println lazyGString == "value == 1"
    
    number = 2
    println eagerGString == "value == 1" // eagerGString已经被固定下来了
    println lazyGString == "value == 2" // lazyGString的值会被重新计算
    

    当一个方法的需要一个java.lang.String变量,而我们传递的是一个groovy.lang.GString实例时,GStringtoString方法会被自动调用,看起来像我们可以直接将一个GString赋值给一个String变量一样。

    注意:GStringString的hashCode是不一样的,即使他们最终结果一样。所以,在Map中,不应该用GString去做元素的Key,而又使用普通的String去取值:

    def key = "a"
    def m = ["${key}": "letter ${key}"] // key类型是一个GString
    assert m["a"] == null // 用一个普通String类型的key去取值
    

    三双引号字符串(Triple double quoted string)

    类似于三单引号字符串,但支持字符串插值。

    斜线字符串(Slashy string)

    除了使用引号来括住字符串,还可以使用/。它一般用来定义正则表达式:

    def fooPattern = /.*foo.*/
    assert fooPattern == '.*foo.*'
    
    def foo = /"yjiyjige"/ // 可以在斜线表达式中,直接使用引号
    println foo // 结果是“yjiyjige”
    

    美元斜线字符串(Dollar slashy string)

    这种字符串使用$/开始,使用/$结束,其中的转义字符为$

    def name = "Guillaume"
    def date = "April, 1st"
    
    def dollarSlashy = $/
        Hello $name,
        today we're ${date}.
    
        $ dollar sign
        $$ escaped dollar sign
         backslash
        / forward slash
        $/ escaped forward slash
        $/$ escaped dollar slashy string delimiter
    /$
    
    assert [
            'Guillaume',
            'April, 1st',
            '$ dollar sign',
            '$ escaped dollar sign',
            '\ backslash',
            '/ forward slash',
            '$/ escaped forward slash',
            '/$ escaped dollar slashy string delimiter'
    ].each { dollarSlashy.contains(it) }
    

    字符串小结

     
     

    字符(Characters)

    在Groovy中并没有明确的字符字面量表示形式,我们必须明确指明:

    char c1 = 'A' // 明确指定给一个字符变量
    assert c1 instanceof Character
    
    def c2 = 'B' as char // 用as关键字
    assert c2 instanceof Character
    
    def c3 = (char) 'C' // 强制类型转换
    assert c3 instanceof Character
    

    数字(Numbers)

    当使用def指明整数字面量时,变量的类型会根据数字的大小自动调整:

    def a = 1
    assert a instanceof Integer
    
    // Integer.MAX_VALUE
    def b = 2147483647
    assert b instanceof Integer
    
    // Integer.MAX_VALUE + 1
    def c = 2147483648
    assert c instanceof Long
    
    // Long.MAX_VALUE
    def d = 9223372036854775807
    assert d instanceof Long
    
    // Long.MAX_VALUE + 1
    def e = 9223372036854775808
    assert e instanceof BigInteger
    

    为了精确地计算小数,在Groovy中使用def声明的小数是BigDecimal类型的:

    def decimal = 123.456
    println decimal.getClass() // class java.math.BigDecimal
    

    如果要强制指明一个数字的字面量类型,可以给字面量加上类型后缀:

    • BigInteger 使用Gg
    • Long 使用Ll
    • Integer 使用Ii
    • BigDecimal 使用Gg
    • Double 使用Dd
    • Float 使用Ff

    列表(List)

    默认情况下Groovy的列表使用的是java.util.ArrayList,用中括号[]括住,使用逗号分隔:

    def numbers = [1, 2, 3]
    println numbers.getClass() // class java.util.ArrayList
    

    如果要使用其它类型的列表(如:LinkedList)可以使用as操作符或显式分配给一个指定类型的变量:

    def arrayList = [1, 2, 3] // 默认类型
    assert arrayList instanceof java.util.ArrayList
    
    def linkedList = [2, 3, 4] as LinkedList // 使用as操作符
    assert linkedList instanceof java.util.LinkedList
    
    LinkedList otherLinked = [3, 4, 5] // 显式指明类型
    assert otherLinked instanceof java.util.LinkedList
    

    Groovy重载了列表的[]<<操作符,可以通过List[index]访问指定位置元素,也可以通过List << element往列表末尾添加元素:

    def letters = ['a', 'b', 'c', 'd']
    
    assert letters[0] == 'a'
    assert letters[1] == 'b'
    
    assert letters[-1] == 'd' // 从后面访问
    assert letters[-2] == 'c'
    
    letters[2] = 'C' // 直接修改
    assert letters[2] == 'C'
    
    letters << 'e' // 往最后面添加元素
    assert letters[4] == 'e'
    assert letters[-1] == 'e'
    
    assert letters[1, 3] == ['b', 'd'] // 提取指定元素
    assert letters[2..4] == ['C', 'd', 'e'] // 支持范围(ranges)操作
    
    // 二维列表
    def multi = [[0, 1], [2, 3]]
    assert multi[1][0] == 2
    

    数组(Arrays)

    在Groovy中,没有数组的字面量定义方式。和特定类型列表的定义方式一样,我们需要使用as操作符或显式地分配给一个数组类型的变量:

    String[] arrStr = ['Ananas', 'Banana', 'Kiwi'] // 显式指明类型
    assert arrStr instanceof String[]
    assert !(arrStr instanceof List)
    
    def numArr = [1, 2, 3] as int[] // 使用as操作符
    assert numArr instanceof int[]
    assert numArr.size() == 3
    

    映射(Maps)

    Groovy使用中括号[]来定义映射,元素需要包含key和value使用冒号分隔,元素与元素之间用逗号分隔:

    // key部分其实是字符串
    def colors = [red: '#FF0000', green: '#00FF00', blue: '#0000FF']
    
    assert colors['red'] == '#FF0000' // 使用中括号访问
    assert colors.green == '#00FF00' // 使用点表达式访问
    
    colors['pink'] = '#FF00FF'
    colors.yellow = '#FFFF00'
    assert colors.pink == '#FF00FF'
    assert colors['yellow'] == '#FFFF00'
    
    assert colors instanceof java.util.LinkedHashMap // 默认使用LinkedHashMap类型
    

    在上边的例子中,虽然没有明确的使用字符串’red‘’green‘,但Groovy会自动把那些key转化为字符串。并且,在默认情况下,初始化映射时,key也不会去使用已经存在的变量:

    def keyVal = 'name'
    def persons = [keyVal: 'Guillaume'] // 此处的key是字符串keyVal而不是name
    
    assert !persons.containsKey('name')
    assert persons.containsKey('keyVal')
    

    如果要使用一个变量作为key,需要用括号括住:

    def keyVal = 'name'
    def persons = [(keyVal): 'Guillaume'] // 相当于[ 'name' : 'Guillaume' ]
    
    assert persons.containsKey('name')
    assert !persons.containsKey('keyVal')
  • 相关阅读:
    Codeforces-799C-Fountains(分类讨论+线段树)
    HDU-3486-Interviewe(二分+RMQ)
    小技巧---查doc文档的index.html怎么用的和chm一样
    chm文件右边部分查看不了
    最长公共临时文档7
    拓展欧几里得临时文档5
    关于myeclipse代码提示的一些问题
    mysql--乱码
    三分--Football Goal(面积最大)
    printf的一个常用技巧
  • 原文地址:https://www.cnblogs.com/Im-Victor/p/10820553.html
Copyright © 2020-2023  润新知