《Groovy语言规范》-语法(三)

5.4.数字类型后缀

通过使用大写或小写类型后缀(见下表),我们能强制将一个数字(包括二进制,八进制,十六进制)给一个指定类型。

Type            Suffix
BigInteger      G 或 g
Long            L 或 l
Integer         I 或 i
BigDecimal      G 或 g
Double          D 或 d
Float           F 或 f

如:

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

5.5.数学运算

尽管运算在以后会被覆盖,讨论数学运算和结果类型仍然是重要的。
除法与幂方二元操作符放在一边(下文讨论)。

  • byte char short和int进行二元操作的结果是int
  • 使用long与byte char short int进行二元操作的结果是long
  • 使用BigInteger与任意其他整数类型进行二元操作结果是BigInteger
  • float double与BigDecimal进行二元运算的结果是double
  • 两个BigDecimal进行二元运算的结果是BigDecimal

下表总结了这些原则:

        byte    char    short    int    long    BigInteger    float      double    BigDecimal
byte    int     int     int      int    long    BigInteger    double     double    double
char            int     int      int    long    BigInteger    double     double    double
short                   int      int    long    BigInteger    double     double    double
int                              int    long    BigInteger    double     double    double
long                                    long    BigInteger    double     double    double
BigInteger                                      BigInteger    double     double    double
float                                                         double     double    double
double                                                                   double    double
BigDecimal                                                                         BigDecimal

由于Groovy操作符重载,BigInteger与BigDecimal通常也能进行运算操作,与Java不同,在Java中你不得不显式使用方法操作这些数字。

5.5.1除法运算符的情况

如果任何一个操作数是float或double,那么除法运算符/(和/= 用于除法和赋值)产生double结果,否则(当两个操作数是一个与整型类型short, char, byte, int, long, BigInteger or BigDecimal的任意组合)是一个BigDecimal结果。

如果除法是精确的(如,结果可以在相同的精度和标度范围内精确表示),那么BigDecimal的除法实际执行的是divide()方法,或使用两个操作数的最大精度加10,和一个最大值为10的标度的MathContext。

对于整数除法和Java相同,你应该使用intdiv()方法,因为Groovy没有专门提供一个整数操作符。

5.5.2.幂运算情况

幂运算操作符使用**操作符,有两个参数:基数和指数。幂运算的结果取决于它的操作数以及操作的结果(特别是结果可以被表示为一个整数值)。

以下这些原则被用于决定Groovy幂运算操作结果的类型:

(1)如果指数是一个小数
	1.如果结果能作为一个Integer表示,那么返回一个Integer
	2..如果结果能作为一个Long表示,那么返回一个Long
	3.否则返回一个Double

(2)如果指数是一个整数
 	1.如果是一个严格的负数,那么返回一个Integer,Long或Double,结果值使用那种类型填充。
        2.如果指数是正数或0
 	  1)如果基数是BigDecimal,那么返回一个BigDecimal结果值
	  2)如果基数是BigInteger,那么返回一个BigInteger结果值
	  3)如果基数是Integer,那么返回一个Integer值,否则返回BigInteger
	  4)如果基数是Long,那么返回一个Long值,否则返回BigInteger

我们使用一些实例说明这些原则:

// base and exponent are ints and the result can be represented by an Integer
assert 2 ** 3 instanceof Integer // 8
assert 10 ** 9 instanceof Integer // 1_000_000_000

// the base is a long, so fit the result in a Long
// (although it could have fit in an Integer)
assert 5L ** 2 instanceof Long // 25

// the result can't be represented as an Integer or Long, so return a BigInteger
assert 100 ** 10 instanceof BigInteger // 10e20
assert 1234 ** 123 instanceof BigInteger // 170515806212727042875...

// the base is a BigDecimal and the exponent a negative int
// but the result can be represented as an Integer
assert 0.5 ** -2 instanceof Integer // 4

// the base is an int, and the exponent a negative float
// but again, the result can be represented as an Integer
assert 1 ** -0.3f instanceof Integer // 1

// the base is an int, and the exponent a negative int
// but the result will be calculated as a Double
// (both base and exponent are actually converted to doubles)
assert 10 ** -1 instanceof Double // 0.1

// the base is a BigDecimal, and the exponent is an int, so return a BigDecimal
assert 1.2 ** 10 instanceof BigDecimal // 6.1917364224

// the base is a float or double, and the exponent is an int
// but the result can only be represented as a Double value
assert 3.4f ** 5 instanceof Double // 454.35430372146965
assert 5.6d ** 2 instanceof Double // 31.359999999999996

// the exponent is a decimal value
// and the result can only be represented as a Double value
assert 7.8 ** 1.9 instanceof Double // 49.542708423868476
assert 2 ** 0.1f instanceof Double // 1.0717734636432956

6.布尔

Boolean是一种特殊的数据类型,用于表示真值:true和false。使用这种数据类型作为跟踪真假条件的简单标志。
Boolean能被存储在变量中,成员变量中,就像其他数据类型一样:

def myBooleanVariable = true
boolean untypedBooleanVar = false
booleanField = true

true和false是仅有的两个原始布尔值。但更复杂的布尔表达式能使用逻辑操作符表示。
除此之外,Groovy有一些特殊的规则(经常因为Groovy真值涉及)用于将非布尔值对象转化为一个布尔值。

7.列表

Groovy使用逗号分隔列表中的值,并使用方括号包围,用来指定一个列表。Groovy的列表是java.util.List,因为Groovy没有定义任何集合类。当定义一个列表常量时,默认的列表具体实现是java.util.ArrayList,除非你指定,我们将在后面看到。

def numbers = [1, 2, 3] (1)

assert numbers instanceof List (2)
assert numbers.size() == 3 (3)

(1)我们定义用逗号分隔,并用方括号包围列表数字,并将列表赋值给一个变量
(2)list是java java.util.List接口的实例
(3)列表的大小可以使用size()方法查询,表明列表有三个元素

在上面的示例中,我们使用了一个元素类型相同的列表,我们也能创建包含不同类型元素的列表:

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

(1)我们的列表包含一个数字,一个字符串,一个布尔值

我们提及到,默认的列表字面量实际是java.util.ArrayList的实例,但列表使用不同返回类型也是可以的,使用as操作符进行类型转换,或使用变量的定义类型:

def arrayList = [1, 2, 3]
assert arrayList instanceof java.util.ArrayList

def linkedList = [2, 3, 4] as LinkedList (1)
assert linkedList instanceof java.util.LinkedList

LinkedList otherLinked = [3, 4, 5] (2)
assert otherLinked instanceof java.util.LinkedList

(1)我们使用as操作符进行类型转换,显式请求一个java.util.LinkedList实现
(2)我们使用类型为java.util.LinkedList的变量保存列表字面量

你能通过下标操作符[](读和写元素值)并使用正索引值访问列表元素或负索引值从列表尾部访问元素,也可以使用范围,或使用左移<<追加列表元素:

def letters = ['a', 'b', 'c', 'd']

assert letters[0] == 'a' (1)
assert letters[1] == 'b'

assert letters[-1] == 'd' (2)
assert letters[-2] == 'c'

letters[2] = 'C' (3)
assert letters[2] == 'C'

letters << 'e' (4)
assert letters[ 4] == 'e'
assert letters[-1] == 'e'

assert letters[1, 3] == ['b', 'd'] (5)
assert letters[2..4] == ['C', 'd', 'e'] (6)

(1)访问列表的第一个元素(索引从零开始计算)
(2)使用负索引访问列表的最后一个元素:-1是列表从尾部开始的第一个元素
(3)使用赋值操作为列表的第三个元素设置一个新值
(4)使用<<左移操作符在列表尾部追加一个元素
(5)一次访问两个元素,并返回一个包含这两个元素的新列表
(6)使用范围访问列表中这个范围内的元素,从start到end元素位置

因为列表可以很自然的做到元素类型不同,因此列表也可以包含列表用于创建多维列表:

def multi = [[0, 1], [2, 3]] (1)
assert multi[1][0] == 2 (2)

(1)定义一个数字列表的列表
(2)访问顶级列表的第二个元素,内部列表的第一个元素

8.数组

Groovy使用列表标记来标记数组,但为了创建字面量数组,你需要通过类型转换或类型定义来定义数组类型。

String[] arrStr = ['Ananas', 'Banana', 'Kiwi'] (1)

assert arrStr instanceof String[] (2)
assert !(arrStr instanceof List)

def numArr = [1, 2, 3] as int[] (3)

assert numArr instanceof int[] (4)
assert numArr.size() == 3

(1)使用显式变量类型定义一个字符串数组
(2)断言说明我们创建了一个字符串数组
(3)使用as操作符创建以int数组
(4)断言表明我们创建了一个原始类型的int数组

你也能创建多维数组:

def matrix3 = new Integer[3][3] (1)
assert matrix3.size() == 3

Integer[][] matrix2 (2)
matrix2 = [[1, 2], [3, 4]]
assert matrix2 instanceof Integer[][]

(1)你能定义一个新数组的边界
(2)或不指定它的边界定义一个新数组

通过与列表相同的标记访问数组的元素:

String[] names = ['Cédric', 'Guillaume', 'Jochen', 'Paul']
assert names[0] == 'Cédric' (1)

names[2] = 'Blackdrag' (2)
assert names[2] == 'Blackdrag'

(1)取得数组的第一个元素
(2)为数组的第三个元素设置一个新值

Java数组初始化标记Groovy不支持,因为大括号会被误解为Groovy的闭包标记。

9.映射

在其它语言中,有时候称为字典或关联数组,Groovy称为映射。映射使键到值关联,使用冒号将键值分隔开,每个键值对使用逗号,整个键和值使用方括号包围。

def colors = [red: '#FF0000', green: '#00FF00', blue: '#0000FF'] (1)

assert colors['red'] == '#FF0000' (2)
assert colors.green == '#00FF00' (3)

colors['pink'] = '#FF00FF' (4)
colors.yellow = '#FFFF00' (5)

assert colors.pink == '#FF00FF'
assert colors['yellow'] == '#FFFF00'

assert colors instanceof java.util.LinkedHashMap

(1)我们定义了一个字符串颜色名关联十六进制的html颜色的映射
(2)我们使用下标标记检查red键值关联的内容
(3)我们也能使用属性标记访问绿颜色十六进制表达式
(4)相似的,我们也能使用下标标记添加一个新的键值对
(5)或者使用属性标记添加yellow颜色

当使用这些键的名字时,我们实际上在映射中定义了一个键值。
Groovy创建的映射实际是java.util.LinkedHashMap的实例。

如果你尝试在映射中访问不存在的键:

assert colors.unknown == null

你将取回null。

在上面的示例中我们使用字符串键值,你也可以使用其他类型作为键值:

def numbers = [1: 'one', 2: 'two']

assert numbers[1] == 'one'

这里我们使用数字作为键值,作为数字能清楚的识别数字,因此Groovy不会像之前的示例一样创建一个字符串的键。但是考虑你想传递一个变量代替键的情况下,有一个变量值将会作为键:

def key = 'name'
def person = [key: 'Guillaume'] (1)

assert !person.containsKey('name') (2)
assert person.containsKey('key') (3)

(1)key同’Guillaume’关联,名字将会变为”key”字符串,而不是其值
(2)这个映射不包括”name”键
(3)代替的是,映射包括一个”key”键

你也能通过引用的字符串以及键: [“name”: “Guillaume”]。如果你的见字符串不是一个合法的标识符,这是强制的,例如,如果你想创建一个字符串键像哈希:

["street-name": "Main street"]。

在映射定义中需要传递变量值,你必须使用圆括号包围这个变量或表达式:

person = [(key): 'Guillaume'] (1)

assert person.containsKey('name') (2)
assert !person.containsKey('key') (3)

(1)这次,我们使用圆括号包围key变量,指示解析器我们传递一个变量,而不是定义一个字符串键
(2)映射包含name键
(3)但映射不像之前包含key键

时间: 2024-12-28 04:55:18

《Groovy语言规范》-语法(三)的相关文章

《Groovy语言规范》-语法

原文链接  译者:王山山 语法 本章节涵盖了Groovy编程语言的语法.Groovy语言的语法源自Java语法,为Groovy增强了特定构造,允许一定程度上的简化语法. 1.注释 1.1.单行注释 单行注释以//开始,在一行中任何位置都可以被发现.//后面的字符,直到一行的末尾都是注释的一部分. // a standalone single line comment println "hello" // a comment till the end of the line 1.2.多行

《Groovy语言规范》-语法(一)

语法 本章节涵盖了Groovy编程语言的语法.Groovy语言的语法源自Java语法,为Groovy增强了特定构造,允许一定程度上的简化语法. 1.注释 1.1.单行注释 单行注释以//开始,在一行中任何位置都可以被发现.//后面的字符,直到一行的末尾都是注释的一部分. // a standalone single line comment println "hello" // a comment till the end of the line 1.2.多行注释 一个多行注释以/*开

C#2.0语言规范(三)匿名方法

规范 第三章 匿名方法原著:Microsoft Corporation原文:http://msdn.microsoft.com/vcsharp/team/language/default.aspx (SpecificationVer2.doc)翻译:lover_P出处: -------------------------------------------------------------------------------- [内容] 3.1 匿名方法表达式 3.2 匿名方法签名 3.3 匿

《Groovy语言规范》-语法(二)

4.6.斜杠字符串 除了通常的带引号字符串,groovy提供斜杠字符串,使用/作为分隔符.斜杠字符串对于定义正则表达式和模式是特别有用的,因为不需要转义反斜杠. 一个斜杠字符串: def fooPattern = /.*foo.*/ assert fooPattern == '.*foo.*' 只有正斜杠需要反斜杠转义: def escapeSlash = /The character \/ is a forward slash/ assert escapeSlash == 'The chara

C语言的语法风格与代码书写规范指南_C 语言

C代码: #include <stdio.h> int main(void) { printf("That is Right Style\n"); return 0; } 在一个标准的C语言程序中,最特殊的莫过于main函数了,而说到底它就是一个函数而已,仅仅因为它地位特殊拥有第一执行权力,换句话说,难道因为一个人是省长它就不是人类了?所以函数该有的它都应该有,那么函数还有什么呢? 函数大体上分为内联函数(C99)(内联函数并非C++专属,C语言亦有,具体见前方链接)和非内

Groovy探索之MOP 三 Class、MetaClass和ExpandoMetaClass

Class当然是Groovy语言从Java语言继承来的,这就是说Groovy语言也继承了Java语言的反射机制.这意味着我们能够像在Java语言里使用反射那样,在Groovy语言里写出诸如下面的代码: import java.lang.reflect.Method class Testor { def testDelegate() { 'ok' } static void main(args) { def t = new Testor() Class cls = t.class Method m

分清“语言/规范”以及“平台/实现”,以及跨平台.NET开发

在许多年前,"语言"就等同于"平台",例如C,C++以及最早的Ruby和Python等等.但是随着技术发展,出现了一些通用的平台,例如.NET和Java,逐渐这些平台上的语言也越来越多.再后来,某些语言在不同平台上的实现也越来越多,事情也变得有些复杂.技术在发展,但是从目前社区的讨论中,我发现许多朋友的观念还没有跟上.简单地说,如今的观念,一定要从"语言即平台"切换成"语言及平台",当分清"语言"和&quo

求教:Eclipse如何为新语言配置语法高亮?

问题描述 一个很小众的编程语言,想尝试用Eclipse作为IDE,有关键词若干,希望实现语法高亮和代码提示.请问该如何配置?小弟新手上路,请予指教,烦请讲详细一点.谢谢先 解决方案 解决方案二:eclipse语法提示(红色波浪线)如何开启关闭设置步骤:windows-->perferences-->editors-->texteditor-->annotation在里面选择errors,把其中的三个选项都勾上就可以啦代码提示按alt+/实现语法高亮是系统自带的,不用设置解决方案三:

一起谈.NET技术,分清“语言/规范”以及“平台/实现”,以及跨平台.NET开发

在许多年前,"语言"就等同于"平台",例如C,C++以及最早的Ruby和Python等等.但是随着技术发展,出现了一些通用的平台,例如.NET和Java,逐渐这些平台上的语言也越来越多.再后来,某些语言在不同平台上的实现也越来越多,事情也变得有些复杂.技术在发展,但是从目前社区的讨论中,我发现许多朋友的观念还没有跟上.简单地说,如今的观念,一定要从"语言即平台"切换成"语言及平台",当分清"语言"和&quo