3. Típusok, típuskonstrukciók
Természetesen a Groovy rendelkezik a Java összes beépített típusával, és típuskonstrukcióival, bizonyos esetekben az adott típus bővebb (pl.: String).
Új típusokat, típuskonstrukciókat is definiáltak a Groovyban.
Típusok
Szám típusok
Integer típus:
3 alaptípus definiált: Integer, Long, BigInteger. Az előbbi kettő limitált (mint általában):
assert Integer.MAX_VALUE == 2147483647
assert Integer.MIN_VALUE == -2147483648
assert Long.MAX_VALUE == 9223372036854775807
assert Long.MIN_VALUE == -9223372036854775808
A BigInteger nem limitált.
Ha explicit nem adjuk meg melyik egész számtípusba tartozzon a változó, akkor automatikusan a legkisebbe kerül, amibe még belefér.
Egész számokat 10/16/8-as számrendszerben is ábrázolhatunk:
//10-es számrendszerben egészek, pozitívak vagy negatívak...
[ 2, -17, +987 ].each{ assert it }
//16-os kezdő 0x-el (kis- vagy nagybetűkkel megadva az a,b,c,d,e,f,x)...
[ 0xACe, 0X01ff ].each{ assert it }
//8-as számrendszerben, vezető 0-val
[ 077, 01 ].each{ assert it }
Egy egész értéknek megadhatjuk a típusát is, úgy, hogy a szám mögé(mindegy milyen reprezentációban írtuk) írjuk a típus betüjelét (Integernek i, Longnak l, BigIntegernek b).
assert 42i.class == Integer //kis i jobban olvasható
assert 123L.class == Long //nagy L jobban olvasható
assert 456g.class == BigInteger
assert 0xFFi.class == Integer
További két fix méretű egész típus a Byte és a Short.
A típusokra, a nagybetűs típusneveken kívül, a "hagyományosabb" módon is hivatkozhatunk (szokták primitív típusoknak is nevezni ezeket):
assert Integer.TYPE == int
assert Long.TYPE == long
assert Short.TYPE == short
assert Byte.TYPE == byte
Fix méretű egészek automatikusan készíthetők sztringekből:
assert '42'.toInteger() == 42i
assert '56'.toLong() == 56L
try{ 'moo'.toLong(); assert false }
catch(e){ assert e instanceof NumberFormatException }
assert new Integer( '45' ) == 45i
assert new Byte( '45' ) == 45 as byte
try{ new Integer( 'oink' ); assert false }
catch(e){ assert e instanceof NumberFormatException }
Természetesen fix méretű egészek is átalakíthatók sztringekké:
//second character is the base/radix...
assert Integer.toString( 29, 16 ) == '1d'
//Long version behaves just like Integer version...
assert Long.toString( 29L, 16 ) == '1d'
//if number is negative, so is first character of returned string...
assert Integer.toString( -29, 16 ) == '-1d'
//only time result begins with zero is if it is zero...
assert Integer.toString(0) == '0'
assert Integer.toString( 29, 16 ).toUpperCase() == '1D'
//second argument defaults to 10...
assert Integer.toString( 29 ) == '29'
//Short version only accepts one parameter, only allowing base 10...
assert Short.toString( 29 as short ) == '29'
Tehát nyelvi szinte támogatott mindkét irányba történő konverzió.
Decimális típus:
Csak tízes számrendszerbeli ábrázolása van: decimális rész, amit követhet a tíz hatvány előjellel: 123.5E-4
Lebegőpontos típus:
Két altípusa lehet: Float és Double. Mind a kettő fix méretű, éppen ezért hatékonyabban lehet ezekkel a típusokkal számolni. Mindkettőhöz előre definiált konstans a +/- végtelen.
Dátum és Idő típus:
Ezek is a számtípusokhoz tartoznak. Lehet növelni, csökkenteni, összehasonlítani dátumokat. Formázott sztringgé is alakítható.
Beállítható a naptár típusa is: Julian/Gregorian.
Kollekciók
Listák és halmazok:
A list objektumok rendezett csoportja. Minden lista kifejezés a java.util.List egy implementációját hozza létre valamilyen speciális lista implementációval.
def list = [1, 2, 3, 4]
assert list[2] == 3
assert list instanceof java.util.List
assert list.class == ArrayList
A lista maga is kiértékelhető mint egy logikai érték: ha üres akkor hamis értéket ad, minden más esetben igazat.
'[]' operátorral egy üres listát hozhatunk létre, és a '<<' operátorral elemeket tehetünk bele.
Az 'each' és az 'eachWithIndex' műveletekkel minden elemen végrehajtathatunk valamilyen kódot:
[1, 2, 3].each{ println "Item: $it" }
['a', 'b', 'c'].eachWithIndex{ it, i -> println "$i: $it" }
Tömbök:
Fix hosszúságú objektumok sorozata. A Java tömbökhöz teljesen hasonló.
Tartomány típus: speciálisan létrehozott tömb típus, segítségével egymás után következő elemek listáját hozhatjuk létre.
// an inclusive range
def range = 5..8
assert range.size() == 4
assert range.get(2) == 7
assert range[2] == 7
assert range instanceof java.util.List
assert range.contains(5)
assert range.contains(8)
// lets use an exclusive range
range = 5..<8
assert range.size() == 3
assert range.get(2) == 7
assert range[2] == 7
assert range instanceof java.util.List
assert range.contains(5)
assert ! range.contains(8)
A tartományokat tetszőleges típusú objektumokból képezhetünk, amik megvalósítják a Comperable interfészt és rendelkeznek next(), previous() metódusokkal. A String például ilyen:
def range = 'a'..'d'
assert range.size() == 4
assert range.get(2) == 'c'
assert range[2] == 'c'
assert range instanceof java.util.List
assert range.contains('a')
assert range.contains('d')
assert ! range.contains('e')
Tartományokat használhatunk for ciklusok megadásához.
for (i in 1..10) {
println "Hello ${i}"
}
Mapek:
Map típusú objektumokat(kulcs kollekció párok) az alább illusztrált szintaxis segítségével hozhatunk létre.
def map = [name:"Gromit", likes:"cheese", id:1234]
assert map.get("name") == "Gromit"
assert map.get("id") == 1234
assert map["name"] == "Gromit"
assert map['id'] == 1234
assert map instanceof java.util.Map
def emptyMap = [:]
assert emptyMap.size() == 0
emptyMap.put("foo", 5)
assert emptyMap.size() == 1
assert emptyMap.get("foo") == 5
Szöveges típusok
Karakterek:
A karakter egy Unicode karakter, csak úgy mint a Java-ban. Minden karakter egy alkategóriába tartozik, amit a getType() függvénnyel le is kérhetünk. Ilyen kategória például a kis betűk/nagybetűk halmaza.
Sztringek:
Karakterek egy sorozata. " vagy ' közé tett karaktersorozattal létrehozható sztring.
Visszaperjellel karakterket a kódjukkalis megadhatjuk:
assert '\b' == '\010' //backspace
assert '\t' == '\011' //horizontal tab
assert '\n' == '\012' //linefeed
assert '\f' == '\014' //form feed
assert '\r' == '\015' //carriage return
Több soron átívelő sztringek definiálhatók háromszoros idézőjellel:
assert '''hello,
world''' == 'hello,\nworld'
def text = """\
Good morning.
Good night again."""
vagy a hagyományos módon, ekkor minden sor végére kell egy visszaperjel:
assert 'hello, \
world' == 'hello, world'
Sztringben a '$' jellel változót helyezhetünk el:
def name = 'Groovy'
assert "hello $name, how are you today?" == "hello Groovy, how are you today?"
Sőt kódot is elhelyezhetünk, ekkor a beágyazott kódot kapcsos zárójellel kell körbevenni:
def a = 'How are you?'
assert "The phrase '$a' has length ${a.size()}" ==
"The phrase 'How are you?' has length 12"
String Műveletek:
Minden objektum átkonvertálható az ő sztring reprezentációjába. Egyik módszer a .toString() művelet, amivel minden objektum rendelkezik, másik a sztring osztály megfelelő valueOf metódusa.
A sztringeket nagyon sok féleképpen létrehozhatunk, manipulálhatnuk, operátorokat használhatunk rajtuk, konstans listaként a lista összes művelete végrehajtható rajtuk.
A format() függvény-re példa:
//Strings (conversion type 's')
assert String.format('%1$8s', 'hello') == ' hello'
//width (here, 8) is minimum characters to be written
assert String.format('%2$6s,%1$2s', 'a', 'hello') == ' hello, a'
//we can re-order arguments
assert String.format('%1$2s', 7, 'd') == ' 7'
//we can give any type of input; we can ignore arguments
assert String.format('%1s,%2s', null, 'null') == 'null,null'
//null treated as 'null'
assert String.format('%1$2.4s', 'hello') == 'hell'
//precision (here, 4) is maximum characters to be written
//Characters ('c')
assert String.format('%1$c,%2$3c', 65, 66 as byte) == 'A, B'
//convert argument to character; 2nd value 3 chars wide
assert String.format('%-3c', 67 as short) == 'C '
//left-justified with '-' flag; we needn't specify parameter number (1$, etc)
assert String.format('%c', 'D' as char) == 'D'
//Special conversion types:
assert String.format('hello %n world %%') == 'hello \r\n world %'
//platform-specific newline; double % to quote it
//Boolean ('b')
assert String.format('%b, %b, %b, %b, %b, %b',
null, true, false, 0, 1, new Object()) ==
'false, true, false, true, true, true'
A StringBuilder-ek változtatható sztringek. Nagy méretű sztringekkel történő műveletek esetén a StringBuilder-ek hatékonyabbak.
Reguláris kifejezések:
A Groovy nyelvi szinten támogatja reguláris kifejezések használatát ~"pattern" kifejezések segítségével, melyeket Java Pattern objektumokká fordít le. A Groovy ismeri a '=~' és '==~' operátorokat is.
Definiálhatunk sztring mintákat vagy más néven reguláris kifejezéseket, amiket összehasonlíthatunk sztringekkel. Azaz lehetőséget biztosít mintázatok keresésére. Legegyszerűbb formája a reguláris kifejezésnek egy számok és betűk sorozatának sztringje.
A legegyszerűbb kifejezés ami reguláris kifejezést is tartalmaz, az amelyikben megtalálható az '==~' operátor. Például:
"potatoe" ==~ /potatoe/
Az ==~ operátor megmondja a fordítónak, hogy mintát keressen, és ne pontos egyezést (mint az == esetében). A reguláris kifejezést '/' jelek fogják közre.
Reguláris kifejezés operátorai:
a? |
0-szor vagy 1-szer fordul elő az *a* |
'a' vagy üres sztring |
a* |
0-szor vagy többször fordul elő az *a* |
üres sztring vagy 'a', 'aa', 'aaa', stb. |
a+ |
1-szer vagy többször fordul elő az *a* |
'a', 'aa', 'aaa', stb. |
a|b |
*a* vagy *b* |
'a' vagy 'b' - |
. |
bármilyen egyhosszú karakter |
'a', 'q', 'l', '_', '+', stb |
[woeirjsd] |
a felsoroltak közül bármelyik előfordul |
'w', 'o', 'e', 'i', 'r', 'j', 's', 'd' |
[1-9] |
az intervallumba esők közül bármelyik előfordul |
'1', '2', '3', '4', '5', '6', '7', '8', '9' |
[^13579] |
bármilyen karakter, ami nincs a felsorolásban |
even digits, or any other character |
(ie) |
kifejezés csoportosítása (más operátorral való használathoz) |
'ie' |
^a |
*a* előfordul egy sor elején |
'a' |
a$ |
*a* előfordul egy sor végén |
'a' |
Olyan reguláris kifejezés esetén amely olyan karaktert is tartalmaz, ami egyben operátor is, akkor '\'-t kell tenni a karakter elé:
// igazat ad, és minden más, kérdőjelre végződő sztringre is igazat ad(ha nem tartalmaznak másik kérdőjelet)
"How tall is Angelina Jolie?" ==~ /[^\?]+\?/
/ |
[^\?] |
+ |
? |
/ |
kifejezés eleje |
bármilyen karakter, ami nem '?' |
legalább egyszer |
egy kérdőjel |
kifejezés vége |
Példák:
import java.util.regex.Matcher
import java.util.regex.Pattern
assert "cheesecheese" =~ "cheese"
assert "cheesecheese" =~ /cheese/
assert "cheese" == /cheese/ /*they are both string syntaxes*/
// lets create a regex Pattern
def pattern = ~/foo/
assert pattern instanceof Pattern
assert pattern.matcher("foo").matches()
// lets create a Matcher
def matcher = "cheesecheese" =~ /cheese/
assert matcher instanceof Matcher
answer = matcher.replaceAll("edam")
// lets do some replacement
def cheese = ("cheesecheese" =~ /cheese/).replaceFirst("nice")
assert cheese == "nicecheese"
// simple group demo
// You can also match a pattern that includes groups. First create a matcher object, either
// using the Java API, or more simply with the =~ operator. Then, you can index the matcher
// object to find the matches. matcher[0][1] means the 0th match of the whole pattern (with the
// =~ operator the pattern may match the string in more than one place), and the 1st group within
// that match. Here's how it works:
def m = "foobarfoo" =~ /o(b.*r)f/
assert m[0][1] == "bar"
// fancier group demo
matcher = "\$abc." =~ "\\\$(.*)\\."
matcher.matches(); // must be invoked [Question: is this still true? Not in my experience with jsr-04.]
assert matcher.group(1) == "abc" // is one, not zero
// assert matcher[1] == "abc" // This has worked before jsr-03-release
assert matcher[0] == ["\$abc.", "abc"] // But this should work since jsr-03-release
assert matcher[0][1] == "abc" // This should work since jsr-03-release
Bemenet és Kimenet
Fájlok:
Operációs rendszertől függő karakterek lekérdezhetőek, amik részt vesznek a fájlformázásokban (pl. Windows-on):
assert File.separator == '\\' && File.separatorChar == '\\' as char
//fájlnevek formázásához használt karakter
assert File.pathSeparator == ';' && File.pathSeparatorChar == ';' as char
A Java-val megegyező
Adatfolyamok:
A Java-val megegyező