groovy快速上手第2篇:数据类型篇
了解一门语言,那么了解她的语法特性必不可少,groovy针对java语言的书写要求做了很多简化。下面直接开始总结groovy的语法特点
注释
groovy的注释与java保持一致
- 单行注释
//这是groovy的单行注释
println 'hello world'
- 多行注释
/*多行注释1
多行注释2 */
println 1+2
- doc注释,groovy3+后支持运行时保存doc内容
/*** 本方法实现两个数相加并返回结果* @param a 两个数中的一个* @param b 两个数中的一个* @return 求加结果*/
def add(a,b){a+b
}
assert add(1,2) == 3
- shebang line
unix下可以在文件的首航增加一个shebang line注释来表明使用什么命令来执行当前脚本
#! /user/bin/env groovy
println 'hello world'
关键字
groovy的关键字包含了java的关键字,此外还有一些groovy的特有关键字,这里不在列举每一个关键字的作用,和其他语言一样,groovy关键字不能作为变量、方法名、字段名,但可以使用取巧的方式使用关键字来定义方法名(主要应用在DSL中)。
def if = 100//编译报错
def 'abstract'() {println 'function abstract()' }
this.abstract()
标识符
使用标识符来定义变量名、方法名、字段名等信息,groovy的标识符满足以下条件
- 使用0-9数字,26个大小写字母,$符号,拉丁字母(话说没人用吧)
- 不能以数字开头
使用"."操作符时,“.”后面的属性也是有效的标识符,带点的操作符后面可接字符串格式的属性,后面接着讲字符串的相关语法,这里可以先了解下
def map = [:]//定义一个map对象
//像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"//访问map中的值
map.'single quote'
map."double quote"
map.'''triple single quote'''
map."""triple double quote"""
map./slashy string/
map.$/dollar slashy string/$//使用GString设置值
def firstname = "Homer"
map."Simpson-${firstname}" = "Homer Simpson"assert map.'Simpson-Homer' == "Homer Simpson"
字符串
groovy有普通字符串和GString字符串(存在占位符的字符串),并允许你实例化它们
单引号字符串
单引号字符串表示普通字符串,不支持占位符的GString定义
'a single-quote string'
字符串的连接
groovy使用“+”连接字符串,和java保持一致
assert 'ab' == 'a'+'b'
三单引号字符串
支持跨行,不支持GString,并且按照编辑格式保存字符串格式,包括换行和缩进,如果你不想要自动保存其中的换行符,可以使用\去掉
String str = '''
第一行
第二行
第三行\
'''
assert str == '\n第一行\n第二行\n第三行'
转义字符
转义字符为反斜杠“\",转义的内容与大多编程语言保持一致,对于键盘上不存在unicode字符,可以使用\uxxxx(后四位16进制数)来表示
双引号字符
双引号字符如果不存在占位符的情况下是普通字符,存在占位符的情况下是GString字符串
assert "test".getClass() == String
assert "test${i1}".getClass() in GString//注意使用in关键字判断
占位符字符串GString
占位字符串GString表示一个字符串中的某一部分由其它变量组成,占位符的格式为${···},花括号内可以是引用变量,简单表达式。对于表达清晰的点式表达式可以省略花括号只使用$xx.xx表示,如果引用变量是一个对象,则将隐式的调用对象的totring()方法,
def str1 = "test"
def str2 = "this is a ${str1}"
assert str2 == 'this is a test'
assert "this is a $str1" == 'this is a test'
assert "1 + 2 = ${1+2}" == '1 + 2 = 3'
assert "1+2=${println 'hello';def a = 1,b=2,c=a+b}" == '1+2=3'//这里输出hello
def m = [a:1,b:2]
assert "$m.a" == '1' && "$m.b" == '2'
class Person{String nameint age
}
def p = new Person(name:'张三',age:18)
assert "姓名:$p.name,年龄:$p.age" == "姓名:张三,年龄:18"
assert "计算1+2=${clo1(1,2)}"
assert "计算1+2=${->3}" == "计算1+2=3"//占位符内为一个闭包
注意使用简化的占位符是不允许调用方法或闭包,当使用闭包占位时将会出现有趣的情况,惰性加载,即对应的GString会在运行时才会确定最终值,参考如下示例
def num = 1
def eagerGString = "value=$num"
def lazyGString = "value=${->num}"
assert eagerGString == 'value=1'
assert lazyGString == 'value=1'
num = 2
assert eagerGString == 'value=1'
assert lazyGString == 'value=2'//当num的值变化后再获取GString时闭包的GString会更新值,普通占位符GString不会
与java的互操性
无论变量是String还是GString,当使用它作为参数调用java或者groovy的方法时,会自动调用变量的toString()方法进行自动转换
def show(String info){assert info.getClass() == Stringreturn info;
}
def p2 = new Person(name: "李四",age: 25)
def info = "姓名:$p2.name,年龄:${->p2.age}"
assert show(info) == "姓名:李四,年龄:25"
GString与String的不同处
而这属于不同的类,因此即便表示的是同一个字符串,它们的hashCode也不相同,并且GString还有惰性加载,他的hash值可能发生变化,因此不建议使用GString作为Map的key
num=2
assert "value=2".hashCode() != "value=$num".hashCode()
def gStr1 = "value=$num"
def map = ["value=$num":100]
assert map."value=2" == null
三双引号字符串
和三单引号字符串相似,但支持占位符GString
斜线字符串
groovy支持以斜线开头斜线结尾的字符串,并且斜线字符串还支持多行格式和GString,如果一个字符串既包含单引号又包含双引号,使用斜线字符串定义不用使用转义字符。当然斜线字符本身需要转义,转义字符串本身不需要转义,其次不能以转义字符结尾。斜线字符串的作用是定义尽量不使用转义字符的字符串
//str3并不是以制表符\t结尾,而是以一个反斜杠和字符t结尾,这意味着非打印字符只能使用unicode形式
def str3 = /this is a 'text' "string"\t/
assert str3 == "this is a 'text' \"string\"\\t"
因为斜杠字符串如果要包含斜杠的话需要使用转义字符,因此如果要以转义字符结尾的话将会导致终止斜线字符被转义,这里可以使用一个小技巧来实现以反义字符结尾
//def str4 = /text end with \/ //编译错误
def str5 = /text ends with ${'\\'}/使用占位符GString实现反斜线结尾
str5 == 'text ends with \\'
美元斜线字符串
美元斜线字符串显然是为了客服斜线字符串的问题,当字符串里面包括正斜线反斜线等内容时,使用美元斜线字符串似乎是个不错的选择,它支持多行字符串和GString,发现一个bug是不能再美元斜线字符串中定义/$后面紧接非空字符的字符串(类似/$abc这样的字符串),会报No such propety错误
def name = 'Guillaume'
def date = 'April,1st'
def dollarSlash = $/hello $name,today we're ${date}.$ dollar sign$$ escape dollar sign\ backslashy/ forward slash$/ escape forward slash$$$/ escape opening dollar slash$/$$ escape close dollar slash
/$
字符
groovy中没有明确的字符文字,但你可以通过强制转换为字符,有三种转换方式
char char1 = 'A'
def char2 = 'A' as char
def char3 = (char) 'A'
数值
整型数值
与java相同,byte、short、int、long分别从一个字节倍增到8个字节,在使用上比java更加方便,同时当出现像下强转(大数转为小数)时通过截取地位字节实现,自动转换无需显示强转
byte b = 1 //无需java那样需要显式强转,如果超出长度自动截取低位值
short s = 1
int i10 = 1
long l = 1
BigInteger bi = 10
当使用def定义变量式,将自动根据赋值的数值大小确定变量的具体类型
def d1 = 1
assert d1 instanceof Integer
def d2 = 2147483648 + 1//2147483648 = Integer.MAX_VALUE+1,不能使用这个表达式赋值,因为默认两个Integer相加还是Integer类型
assert d2 instanceof Long
def d3 = 9223372036854775808 + 1
assert d3 instanceof BigInteger
数字的其他格式
和java一样,数字也可以使用二进制、八进制、十六进制表示,二进制以ob开头,8进制以0开头,16进制以0x开头,此外对于较长的数字可以使用下划线分隔以便更好的目视。
def bint = 0b1001
def oint = 017
def xint = 0xabc
def i11 = 123_343_123
浮点类型数值
浮点类型包括float和double,分别占长度4字节到8字节,大浮点数字可以使用BigDecimal表示,同时可以使用指数形式表示浮点数值
float f5 = 1.1
double d4 = 1.4
BigDecimal bi2 = 2.1
assert 1e4 == 10000.0
assert 1e4 == 10000
assert 3e-1 == 0.3
assert 5E-2 == 0.05
可以通过数字后缀特定字符来强转数值为指定类型的数字
assert 100i instanceof Integer//100默认值为Integer,可以后缀i强转
assert 100f instanceof Float//后缀f强转float
assert 100D instanceof Double//后缀D或d强转double
assert 100g instanceof BigInteger//后缀g
assert 100.0 instanceof BigDecimal//默认
assert 010g instanceof BigInteger//八进制后缀g
assert 0b1001l instanceof Long//二进制后缀l
assert 0xabcg instanceof BigInteger//16进制后缀g
数值的数学计算结果
参见下图,可以很清晰的看到两个数值的计算结果只会导致结果像更大类型的值拓展,并且自int类型起步,超过int类型类型以最大的那个数值的类型为准,即便发生溢出也不会再向上扩大了(即两个int计算结果一定为int,int与long计算结果为long)
对于除法由特殊规定,当被除数和除数有一个为float或double时,则结果为Double,否则结果为BigDecimal,对于除法产生的精度问题,当能够除尽时将会保留全部精度,不能除尽时将保留10位有效数字(浮点型数值的二进制表示方法)
assert 1234567891f / 1e10 != 0.1234567891
assert 1234567891 / 1e10 == 0.1234567891
幂运算值
幂运算使用 ** 运算符,其结果取决于两个操作数和结果,文档复杂待定
布尔值
布尔值使用特殊的数据类型表示true和false,占用1字节,与java不同的是groovy有特殊的规则来判断一个非布尔值的真假,groovy的规则是判断目标有东西而"非空"则为true,否则为false。这里的非空对于普通对象来说非null,对于集合来说非空集合,对于枚举来说有元素,对于字符串来说非空串,对于数值来说非0.最后一点对于普通类对象来说,可以通过覆写asBoolean方法来自定义它实例的布尔判断
//布尔值直接判断
assert true
assert !false
//非空集合为ture,空集合为false
assert [1,2,3]
assert ![]
assert ('a' =~ /a/)
assert !('a' =~ /b/)
assert [a:1]
assert ![:]
//非空迭代器为true,空迭代器为false
assert [0].iterator()
assert ![].iterator()
def v = [0] as Vector;
//非空列举为true,空列举为false
Enumeration enumeration = v.elements();
assert enumeration
enumeration.nextElement()
assert !enumeration
//非空字符为true,否则为false
assert 'a'
assert !''
//非0值为true,0值为false
assert 1
assert !0
//普通对象为true,null值为false
assert new Object()
assert !null
//自定义类的布尔输出结果
class MyObj{boolean asBoolean(){false}
}
assert !new MyObj()
List
groovy使用一个方括号括起来多个值之间通过逗号分隔的结构来定义List,具体结构使用java的List(默认实现为ArrayList),如果需要其他结构的List,可以通过as关键字另行制定。
- 访问List元素通过list[元素索引位置]来访问,正索引表示从前到后,负索引表示从后到前
- 可以通过逗号分割的多个索引位置来获取一个子List
- 可以通过“…”来获取一个连续范围内的子List
- 可以通过<< 运算符来讲元素添加到List中
def list1 = [1,2,'a',"string info"]
def list2 = [3,4,6] as LinkedList
assert list2 instanceof LinkedList
assert list1[0] == 1
assert list1[-1] == 'string info'
assert list1[1,3] == [2,'string info']
assert list1[0..2] == [1,2,'a']
list1 << 'b'
assert list1[-1] == 'b'
list1[0] = '10'
assert list1[0] == '10'
数组
groovy对数组的语法重用了List,其对元素的访问也和List一样,但数组不支持 << 操作符,此外groovy支持java风格的语法
assert new int[]{1,2,3} instanceof int[]//java风格
assert (int[])[1,2,3] instanceof int[]//强转
int[] arr1 = [4,5,6]//显示类型定义
assert arr1 instanceof int[]
def arr2 = [7,8,9] as int[]//as关键字
assert arr2 instanceof int[]
assert arr1[1] == 5
arr1[1] = 15
assert arr1[1] == 15
assert arr1[-1] == 6
assert arr1[0,1] == (int[])[4,15]
assert arr1[0..2] == (int[])[4,15,6]
Map
groovy使用一个中括号括起来、冒号分隔键值对,多个键值对之家通过逗号分隔的方式定义map,map的key为标准的标识符字符串时可以省略双引号(访问或者赋值均可省略)。
- map的key建议使用字符串、数值等hashcode不会变化的类型值,不建议使用闭包的GString等
- 访问map时key是变量时可以通过GString方式或者讲变量用小括号括起来的方式,当然也可以是用get方法,当使用括号时是告诉解释器传递的是变量而非字符串常量
def color = [blue:'#0000FF',red:'#FF0000',green:'00FF00']
assert color.blue == '#0000FF'
assert color['red'] == '#FF0000'
color.pink = '#FF00FF'
color['yellow'] = '#FFFF00'
assert color['pink'] == '#FF00FF'
assert color instanceof LinkedHashMap
assert color.unknown == null
color.'my favor color' = '#0F0F0F'
assert color.'my favor color' == '#0F0F0F'
def str6 = 'pop color'
color."$str6" = '#FFFFFF'
assert color["$str6"] == '#FFFFFF'
def str7 = 'bad color'
color[(str7)] = '#000000'
assert color.(str7) == '#000000'
groovy快速上手第2篇:数据类型篇相关推荐
- 快速上手JVM系列(整合篇)
JDK版本:jdk-11.0.7,文中所有代码都在JDK11环境下运行成功 虚拟机版本:Java HotSpot(TM) 64-Bit Server VM 18.9 学习过程中主要参考资料 [1] 深 ...
- 30分钟快速上手Docker,看这篇就对了!
一.历史演化 1.演化史 2.物理机时代 2.1.图解 一个物理机上安装操作系统,然后直接运行我们的软件.也就是说你电脑上直接跑了一个软件,并没有开虚拟机什么的,资源极其浪费. 2.2.缺点 部署慢 ...
- Python快速上手系列--循环结构--基础篇
本篇将讲述前几章都有提起的循环,非常的重要,对于自动化测试的脚本来说,运用的都比较的频繁.好好看. if语句 首先我们先来学习一下if语句,因为它通常会和for循环搭配使用,频率极高. if 关键字或 ...
- Python快速上手系列--列表--详解篇
本章有部分超纲内容,可作为了解,提前学习学习. 列表 列表,主要使用[ ]来表示,我这里的加了一个空格,便于看清哦!看下面的例子 # 这里声明一个变量,后续便于输出class_name = [&quo ...
- Python快速上手系列--类--详解篇
本章是自动化测试的真正开始,因为在后续的过程中,你会接触到unittest框架,pytest框架,而不仅仅只是写一个函数+selenium脚本这么简单了. 1.创建类 1.1.了解类 我们首先了解一下 ...
- vs转eclipse之工具快速上手篇
eclipse工具下载 首先说明,本篇内容适用于刚开始学java的同学,老手大牛等可以路过. 不得不说vs确实很强大,常用的都在安装包里集成了,几乎可以一键安装,直接使用,操作起来非常方便. ecli ...
- c语言 字符串转运算符,快速上手系列-C语言之基础篇(二)数据类型与运算符...
在上一篇文章<快速上手系列-C语言之基础篇(一)>中写了关于C语言的程序结构,关键字及控制语句.本篇主要写写C语言中数据类型,以及运算符相关方面的知识. 一.变量与常量 1.常量:在程序运 ...
- 【Python五篇慢慢弹】快速上手学python
快速上手学python 作者:白宁超 2016年10月4日19:59:39 摘要:python语言俨然不算新技术,七八年前甚至更早已有很多人研习,只是没有现在流行罢了.之所以当下如此盛行,我想肯定是多 ...
- pyqt5从子目录加载qrc文件_PyQt5快速上手基础篇10-QSettings用法
前言 本节我们学习使用PyQt5的QSettings的用法,使用QSettings可以记住用户操作UI界面设置的参数,下次打开软件的时候,会直接加载用户上一次设置的参数. 一.基础知识 1.QSett ...
最新文章
- 第十六届全国大学生智能车竞赛线上赛点赛道审核 - 西部赛区
- pip 系统无法将文件移到不同的磁盘驱动器 的问题
- 方正魏新:我们走的产业路线比联想高端
- BZOJ 1011: [HNOI2008]遥远的行星
- Bigtable数据模型和架构
- spring hsqldb_在Spring中嵌入HSQLDB服务器实例
- 向 mysql导入数据 源码_MySQL 导入数据
- 手把手教你用 elementUI 实现导航栏
- python水平_如何在python中水平透视表
- 前端基础-html-音频标签的介绍
- 『Linux』ArchLinux与VirtualBox的结合「二」
- 原生 javascript 操作 websocket
- 让自己的软件出现在选择打开列表的软件中
- Java中定时任务的6种实现方式,你知道几种?
- 简易歌曲推荐网页制作
- maple 求特征值
- 无线上外网,有线上内网的方式(转)
- odbc配置以及一个简单的java连接的代码编写
- iOS模拟各种网络状态
- 面试题练习(Java基础(一))