当前位置:   article > 正文

Groovy入门(一)—— Groovy语法_groovy去除换行符

groovy去除换行符

Groovy语法

1. 注释

1.1. 单行注释

Groovy单行注释以//开头,可以出现在程序的各个位置。

  1. // a standalone single line comment
  2. println "hello" // a comment till the end of the line
1.2. 多行注释

多行注释以 /* 开头,以 */ 结尾,可以出现在程序的任何位置。

  1. /* a standalone multiline comment
  2. spanning two lines */
  3. println "hello" /* a multiline comment starting
  4. at the end of a statement */
  5. println 1 /* one */ + 2 /* two */
1.3. GroovyDoc

GroovyDoc以 /** 开头,以 */结尾,中间行一般可以选择性的以 * 开头。

GroovyDoc一般用于:

  • 类型定义 (classes, interfaces, enums, annotations)
  • 字段或属性定义
  • 方法定义
  1. /**
  2. * A Class description
  3. */
  4. class Person {
  5. /** the name of the person */
  6. String name
  7. /**
  8. * Creates a greeting method for a certain person.
  9. *
  10. * @param otherPerson the person to greet
  11. * @return a greeting message
  12. */
  13. String greet(String otherPerson) {
  14. "Hello ${otherPerson}"
  15. }
  16. }
1.4. Shebang line

#开头写在文件的第一行,告诉Unix或类Unix系统以何种解释器去运行脚本。前提是已经安装了Groovy,并且配置完PATH。

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

2. 关键字

as assert break case catch class const continue def default do else enum extends false finally for goto if implements import in instanceof interfacenew null package return super switch this throwthrows trait true try while

3. 标识符

3.1. 普通标识符(Normal identifiers)

标识符以字母、$、_开头,不能以数字开头,但后面可以跟数字。

字母的的取值区间为:

  • 'a' to 'z' (lowercase ascii letter)
  • 'A' to 'Z' (uppercase ascii letter)
  • '\u00C0' to '\u00D6'
  • '\u00D8' to '\u00F6'
  • '\u00F8' to '\u00FF'
  • '\u0100' to '\uFFFE'

eg:

  1. def name
  2. def item3
  3. def with_underscore
  4. def $dollarStart
3.2. 引用标识符(Quoted identifiers)

引用标识符是.(dot)后的表达式。比如说nameperson.name的一部分,那么我们可以通过person."name"或者person.'name'来引用它。这点与Java不同,Java不允许这种格式的引用。eg:

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

Groovy提供了不同种类的字符串字面量,所有String类型的字面量都允许写到.后作为引用标识符。eg:

  1. map.'single quote'
  2. map."double quote"
  3. map.'''triple single quote'''
  4. map."""triple double quote"""
  5. map./slashy string/
  6. map.$/dollar slashy string/$

4. String

Groovy支持java.lang.String和GString(groovy.lang.GString)字符串类型,其中GString在一些编程语言中被称作interpolated stringsWikipedia - String interpolation

4.1. 单引号字符串(Single quoted string)

单引号字符串被解释成java.lang.string,不支持内插值。

'a single quoted string'
4.2. 字符串拼接

Groovy中连接字符串使用+

assert 'ab' == 'a' + 'b'
4.3. 三单引号字符串(Triple single quoted string)

三单引号字符串被解释成java.lang.String类型,不支持内插值。

三单引号支持多行,支持文本跨行,并且不需要换行符,字符串原样输出。eg:

  1. def aMultilineString = '''line one
  2. line two
  3. line three'''

通常,代码在格式化完毕之后,会保持缩进。对于三单引号字符串来说,会把缩进也原样输出。Groovy提供了String#stripIndent()方法来去掉字符串前的缩进,并且提供了String#stripMargin()方法,可以删除字符串开始位置的指定分隔符。

当我们创建如下的字符串时:

  1. def startingAndEndingWithANewline = '''
  2. line one
  3. line two
  4. line three
  5. '''

会发现字符串开头包含一个换行符\n,可以通过字符串开头添加``来消除开头的换行符。

  1. def strippedFirstNewline = '''\
  2. line one
  3. line two
  4. line three
  5. '''
  6. assert !strippedFirstNewline.startsWith('\n')
4.4. 双引号字符串
"a double quoted string"

当双引号字符串中没有插值表达式时,字符串的类型为java.lang.String,当双引号字符串中包含插值表达式时,字符串类型为groovy.lang.GString

4.4.1 字符串插值(String interpolation)

除了单引号字符串和三单引号字符串以外,任何Groovy表达式可以出现在所有的字符串字面量中。插值实际上是替换字符串中的占位符。占位符表达式是被${}围绕或以$为前缀的点表达式(dotted expressions),当GString传递给一个以String类型作为参数的方法时,会调用toString方法,将占位符替换为表达式所代表的值。eg:

  1. def name = 'Guillaume' // a plain string
  2. def greeting = "Hello ${name}"
  3. assert greeting.toString() == 'Hello Guillaume'
  1. def sum = "The sum of 2 and 3 equals ${2 + 3}"
  2. assert sum.toString() == 'The sum of 2 and 3 equals 5'

实际上${}中不仅可以使用表达式,也可以写声明语句,但是这些语句的返回值为null,例如"The sum of 1 and 2 is equal to ${def a = 1; def b = 2; a + b}"在Groovy中是被支持的,但是一般在Groovy中不推荐这样写。更好的写法是在GString中只使用简单的占位符。

使用$点表达式(dotted expressions),eg:

  1. def person = [name: 'Guillaume', age: 36]
  2. assert "$person.name is $person.age years old" == 'Guillaume is 36 years old'

使用$点表达式(dotted expressions)的时候,只允许a.ba.b.c的写法,不能调用方法,否则会抛出groovy.lang.MissingPropertyException的异常。因为Groovy在替换插值时调用的是toString方法。

  1. def number = 3.14
  2. shouldFail(MissingPropertyException) {
  3. println "$number.toString()" // groovy.lang.MissingPropertyException
  4. }

"$number.toString()" 替换为 "${number.toString}()" 可以正常运行。

4.4.2. 特殊的插值闭包表达式(Special case of interpolating closure expressions)

闭包表达式的格式为:${->},简单的理解为一个闭包前面加了一个$符号。eg:

  1. def sParameterLessClosure = "1 + 2 == ${-> 3}"
  2. assert sParameterLessClosure == '1 + 2 == 3'
  3. def sOneParamClosure = "1 + 2 == ${ w -> w << 3}"
  4. assert sOneParamClosure == '1 + 2 == 3'

关于闭包表达式:

  • 闭包是无参的
  • 闭包包含一个java.io.StringWriter参数,可以通过追加内容到>>后面的方式添加。

闭包表达式只能有0个或1个参数。

闭包表达式和普通表达式唯一的不同是:lazy evaluation 。详情移步 —> Wikipedia - Lazy evaluation

  1. def number = 1
  2. def eagerGString = "value == ${number}"
  3. def lazyGString = "value == ${ -> number }"
  4. assert eagerGString == "value == 1"
  5. assert lazyGString == "value == 1"
  6. number = 2
  7. assert eagerGString == "value == 1" // eagerGString不会再次求值
  8. assert lazyGString == "value == 2" // lazyGString会再次求值
4.4.3. GString and String hashCodes

尽管GString可以代替String,但是他们还一处不同:他们的hashCodes不同。原生的Java String 是immutable(不可变的),但是GString所表示的String却是可变的,依赖于的它的插值。即使GString和Java原生String类型有相同的字面量,它们的hashCodes的值可能不同。eg:

assert "one: ${1}".hashCode() != "one: 1".hashCode()

由于GString和String的hashCodes不同,所以应该避免使用使用GString作为Map的key。eg:

  1. def key = "a"
  2. def m = ["${key}": "letter ${key}"]
  3. assert m["a"] == null
4.5. 三双引号字符串( Triple double quoted string)

类似于三单引号字符串,支持跨行。也类似双引号字符,支持GString插值操作。

  1. def name = 'Groovy'
  2. def template = """
  3. Dear Mr ${name},
  4. You're the winner of the lottery!
  5. Yours sincerly,
  6. Dave
  7. """
  8. assert template.toString().contains('Groovy')
4.6. Slashy string

/作为界定符的字符串,叫做Slashy string。它通常被用于写正则表达式,因为不需要转译的反斜线``。

  1. def fooPattern = /.*foo.*/
  2. assert fooPattern == '.*foo.*'

如果字符串中间出现/,这种情况下才需要转译。eg:

  1. def escapeSlash = /The character \/ is a forward slash/
  2. assert escapeSlash == 'The character / is a forward slash'

Slashy string允许跨行,eg:

  1. def multilineSlashy = /one
  2. two
  3. three/
  4. assert multilineSlashy.contains('\n')

Slashy string支持插值操作,类似GString。eg:

  1. def color = 'blue'
  2. def interpolatedSlashy = /a ${color} car/
  3. assert interpolatedSlashy == 'a blue car'

如果Slashy string是空字符串//,那么编译过程中会把//当做注释。

4.7. Dollar slashy string

Dollar slashy string相当于跨行的GString,以$/开头,以/$结尾。以$作为转译字符,可以转译另一个$/

4.8. 字符(Characters)

Groovy没有明确的字符类型,可以通过以下三种方式创建:

  1. char c1 = 'A' // 类型声明为char
  2. assert c1 instanceof Character
  3. def c2 = 'B' as char // 通过as将类型强制指定为char
  4. assert c2 instanceof Character
  5. def c3 = (char)'C' // 通过类型转换
  6. assert c3 instanceof Character

5. 数值(Numbers)

5.1. 整型(Integral literals)

Groovy的整型和Java类似:

  • byte
  • char
  • short
  • int
  • long
  • java.lang.BigInteger

eg:

  1. // primitive types 原始类型
  2. byte b = 1
  3. char c = 2
  4. short s = 3
  5. int i = 4
  6. long l = 5
  7. // infinite precision 引用类型
  8. BigInteger bi = 6

如果使用def声明类型,那么这个整型是可变的。它会数值的大小来匹配类型。(负数也如此)

  1. def a = 1
  2. assert a instanceof Integer
  3. // Integer.MAX_VALUE
  4. def b = 2147483647
  5. assert b instanceof Integer
  6. // Integer.MAX_VALUE + 1
  7. def c = 2147483648
  8. assert c instanceof Long
  9. // Long.MAX_VALUE
  10. def d = 9223372036854775807
  11. assert d instanceof Long
  12. // Long.MAX_VALUE + 1
  13. def e = 9223372036854775808
  14. assert e instanceof BigInteger

其它进制:

  • 2进制是以0b开头的数字
  • 8进制是以0开头的数字
  • 16进制是以0x开头的数字
5.2. 浮点数(Decimal literals)

浮点数类型和Java类似:

  • float
  • double
  • java.lang.BigDecimal

浮点数类型支持指数,通过eE实现。

  1. // primitive types
  2. float f = 1.234
  3. double d = 2.345
  4. // infinite precision
  5. BigDecimal bd = 3.456
  6. assert 1e3 == 1_000.0
  7. assert 2E4 == 20_000.0
  8. assert 3e+1 == 30.0
  9. assert 4E-2 == 0.04
  10. assert 5e-1 == 0.5

为了计算的准确性,Groovy使用BigDecimal作为浮点数的默认类型。除非显示的声明floatdouble,否则浮点数类型为java.lang.BigDecimal。尽管如此,在一些接受参数为floatdouble的方法中,依然可以使用BigDecimal类型作为参数传递。

5.3. 数值中使用下划线

当数值过长的时候,可以使用_对数字进行分组,以使阅读更加简洁明了。eg:

  1. long creditCardNumber = 1234_5678_9012_3456L
  2. long socialSecurityNumbers = 999_99_9999L
  3. double monetaryAmount = 12_345_132.12
  4. long hexBytes = 0xFF_EC_DE_5E
  5. long hexWords = 0xFFEC_DE5E
  6. long maxLong = 0x7fff_ffff_ffff_ffffL
  7. long alsoMaxLong = 9_223_372_036_854_775_807L
  8. long bytes = 0b11010010_01101001_10010100_10010010
5.4. 数值类型后缀(Number type suffixes)

可以通过使用后缀来指定数字类型

  • BigInteger类型后缀为Gg
  • Long类型后缀为Ll
  • Integer类型后缀为Ii
  • Bigdecimal类型后缀为Gg
  • Double类型后缀为Dd
  • Float类型后缀为Ff

eg:

  1. assert 42I == new Integer('42')
  2. assert 42i == new Integer('42') // lowercase i more readable
  3. assert 123L == new Long("123") // uppercase L more readable
  4. assert 2147483648 == new Long('2147483648') // Long type used, value too large for an Integer
  5. assert 456G == new BigInteger('456')
  6. assert 456g == new BigInteger('456')
  7. assert 123.45 == new BigDecimal('123.45') // default BigDecimal type used
  8. assert 1.200065D == new Double('1.200065')
  9. assert 1.234F == new Float('1.234')
  10. assert 1.23E23D == new Double('1.23E23')
  11. assert 0b1111L.class == Long // binary
  12. assert 0xFFi.class == Integer // hexadecimal
  13. assert 034G.class == BigInteger // octal

6. Boolean

布尔类型是一种特殊的类型用于判断对或错:truefalse。Groovy有一套特别的规则用于强制将non-boolean类型转换为bollean类型。

7. List

Groovy中没有定义自己的List类型,使用的是java.util.List类型。通过一对[]包括,里面的元素以,分隔来定义一个List。默认情况下,创建的List的类型为java.util.ArrayList。eg:

  1. def numbers = [1, 2, 3]
  2. assert numbers instanceof List
  3. assert numbers.size() == 3

List中元素可以是不同类型:

def heterogeneous = [1, "a", true]

通过使用as操作符可以强制指定List的类型,或者在声明List变量时强制指定类型。eg:

  1. def arrayList = [1, 2, 3]
  2. assert arrayList instanceof java.util.ArrayList
  3. def linkedList = [2, 3, 4] as LinkedList
  4. assert linkedList instanceof java.util.LinkedList
  5. LinkedList otherLinked = [3, 4, 5]
  6. assert otherLinked instanceof java.util.LinkedList

可以使用[]获取List中的元素,可以使用<<向list末尾追加元素。

  1. def letters = ['a', 'b', 'c', 'd']
  2. assert letters[0] == 'a'
  3. assert letters[1] == 'b'
  4. assert letters[-1] == 'd'
  5. assert letters[-2] == 'c'
  6. letters[2] = 'C'
  7. assert letters[2] == 'C'
  8. letters << 'e'
  9. assert letters[ 4] == 'e'
  10. assert letters[-1] == 'e'
  11. assert letters[1, 3] == ['b', 'd']
  12. assert letters[2..4] == ['C', 'd', 'e']

8. Arrays

Groovy定义数组的方式和定义list的方式一样,只不过声明时需要制定类型,或者通过as来强制制定类型为Array。

  1. String[] arrStr = ['Ananas', 'Banana', 'Kiwi']
  2. assert arrStr instanceof String[]
  3. assert !(arrStr instanceof List)
  4. def numArr = [1, 2, 3] as int[]
  5. assert numArr instanceof int[]
  6. assert numArr.size() == 3
  7. //多维数组
  8. def matrix3 = new Integer[3][3]
  9. assert matrix3.size() == 3
  10. Integer[][] matrix2
  11. matrix2 = [[1, 2], [3, 4]]
  12. assert matrix2 instanceof Integer[][]

Groovy不支持Java数组的初始化方式。

9. Maps

Map定义方式为:使用[]包括,里面的元素为key/value的形式,key和value以:分隔,每一对key/value以逗号分隔。Groovy穿件的map默认类型为java.util.LinkedHashMap。eg:

  1. def colors = [red: '#FF0000', green: '#00FF00', blue: '#0000FF']
  2. assert colors['red'] == '#FF0000'
  3. assert colors.green == '#00FF00'
  4. colors['pink'] = '#FF00FF'
  5. colors.yellow = '#FFFF00'
  6. assert colors.pink == '#FF00FF'
  7. assert colors['yellow'] == '#FFFF00'
  8. assert colors instanceof java.util.LinkedHashMap

Map中通过[key].key的方式来获取key对应的value。如果key不存在,则返回null。

当我们使用数字作为key时,这个数字可以明确的认为是数字,并不是Groovy根据数字创建了一个字符串。但是如果以一个变量作为key的话,需要将变量用()包裹起来,否则key为变量,而不是变量所代表的值。eg:

  1. def key = 'name'
  2. def person = [key: 'Guillaume'] // key实际上为"key"
  3. assert !person.containsKey('name')
  4. assert person.containsKey('key')
  5. person = [(key): 'Guillaume'] // key实际上为"name"
  6. assert person.containsKey('name')
  7. assert !person.containsKey('key')


作者:losemycat
链接:http://www.jianshu.com/p/f02b066bb055
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/运维做开发/article/detail/810358
推荐阅读
相关标签
  

闽ICP备14008679号