A Groovy programozási nyelv

Típusok, típuskonstrukciók

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ő