76
技術社區[雲棲]
《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鍵
最後更新:2017-05-22 12:01:28