A ChucK nyelv kétfajta típust különböztet meg: a primitív típusokat és az osztályokat.
Primitív típusok
A primitív, vagy beépített típusok egyszerű, attribútumokkal nem rendelkező típusok. A primitív
típusok paraméterátadása érték szerint történik. A primitív típusokat nem lehet kiterjeszteni.
A nyelvben a következő beépített típusok állnak rendelkezésre:
int
: előjeles egész szám
float
: dupla pontosságú lebegőpontos szám
time
: ChucKi idő
dur
: ChucKi időtartam
void
: üres típus
complex
: komplex szám algebrai (a + bi) alakban megadva
polar
: komplex szám polárkoordinátás alakban megadva
Referencia típusok
Referencia típusok az Object leszármazottjai. Néhány beépített referencia típus:
Object
: minden osztály ősosztálya
array
: N dimenziós tömb
Event
: alapvető, kiterjeszthető szinkronizációs szerkezet
UGen
: kiterjeszthető unit generator ősosztály
string
: karakterlánc
Tömbök
A tömbök az array osztály példányai, tehát referencia típusok.
Deklaráció
Tömbök deklarációja szögletes zárójelekkel történik:
// 10 elemű, int-ekből álló tömb deklarációja foo
int foo[10];
// mivel a tömb elemei int-ek, ami primitív típus,
// automatikusan 0-val inicializálódnak
Tömböket lehet inicializálni tömb konstanssal:
// chuck inicializáló referenciával
[ 1, 1, 2, 3, 5, 8 ] @=> int foo[];
A fenti kód számos szempontból érdekes:
-
A tömb inicializálóknak egyező, vagy hasonló típusú elemeket kell tartalmazniuk.
A fordító megpróbálja megkeresni a típusok legmagasabb ősét, ha ilyet nem talál, hibát jelez.
-
Az
[ 1, 1, 2, 3, 5, 8 ]
inicializáló típusa int
[]
.
Az inicializáló mindenhol használható, ahol tömböt várnak. (Tömb konstans, csak inicializálónak nevezik)
-
Az at-chuck operátor (
@=>
) értékadást jelent, bővebben lásd
az operátorok fejezetnél.
-
Az
int foo[]
egy üres (null
) tömbreferenciát deklarál. Az utasítás ennek adja értékül
az inicializálót.
- A tömbök objektumok.
Objektumok tömbje esetén a tömb minden eleme automatikusan példányosul:
// tömbbeli objektumok automatikusan példányosulnak
Object group[10];
Objektumok referenciájának tömbjét a @
jellel lehet deklarálni:
// nullreferenciák tömbje
Object @ group[10];
Többdimenziós tömbök
Többdimenziós tömbök deklarálása és inicializálása az egydimenziósakhoz hasonlóan történik:
// declare 4 by 6 by 8 array of float
float foo3D[4][6][8];
// declare 2 by 2 array of int
[ [1,3], [2,4] ] @=> int bar[][];
Elemek elérése
Tömbelemek elérése a szögletes zárójellel történik.
// declare an array of floats
[ 3.2, 5.0, 7 ] @=> float foo[];
// access the 0th element (debug print)
<<< foo[0] >>>; // hopefully 3.2
// set the 2nd element
8.5 => foo[2];
Tömb bejárása:
// array of floats again
[ 1, 2, 3, 4, 5, 6 ] @=> float foo[];
// loop over the entire array
for( 0 => int i; i < foo.cap(); i++ )
{
// do something (debug print)
<<< foo[i] >>>;
}
Többdimenziós tömbre:
// 2D array
int foo[4][4];
// set an element
10 => foo[2][2];
Ha az index túlmutat a tömb határain, kivétel váltódik ki, és az aktuális shred (végrehajtási szál) megáll.
// array capacity is 5
int foo[5];
// this should cause ArrayOutOfBoundsException
// access element 6 (index 5)
<<< foo[5] >>>;
Asszociatív tömbök
Bármely tömb használható asszociatív tömbként, stringekkel indexelve.
// declare regular array (capacity doesn't matter so much)
float foo[4];
// use as int-based array
2.5 => foo[0];
// use as associative array
4.0 => foo["yoyo"];
// access as associative (print)
<<< foo["yoyo"] >>>;
// access empty element
<<< foo["gaga"] >>>; // -> should print 0.0
Fontos azonban megjegyezni, hogy a számmal és a stringgel indexelt rész teljesen külöböző! Példával illusztrálva:
// declare array
int foo[2];
// put something in element 0
10 => foo[0];
// put something in element "0"
20 => foo["0"];
// this should print out 10 20
<<< foo[0], foo["0"] >>>;
A tömb kapacitása csak a számmal indexelt részre vonatkozik.
// declare array of 0 capacity
int foo[0];
// put something in element "here"
20 => foo["here"];
// this should print out 20
<<< foo["here"] >>>
// this should cause an exception
<<< foo[0] >>>
Megjegyzés: a tömb asszociatív kapacitása nincs definiálva, ezért az asszociatív tömbben tárolt
objektumokat explicit példányosítani kell, ellentétben az egésszel indexelttel. Egy inicializálatlan elem
lekérdezése null referenciát fog eredményezni.
class Item {
float weight;
}
Item box[10];
// integer indices ( up to capacity ) are pre-instantiated.
1.2 => box[1].weight;
// instantiate element "lamp";
new Item @=> box["lamp"];
// access allowed to "lamp"
2.0 => box["lamp"].weight;
// access causes a NullPointerException
2.0 = box["sweater"].weight;
Tömbre vonatkozó értékadás
Mivel a tömbök objetumok, deklarációjuk során először egy tömbreferenciát deklarálunk, majd ennek adjuk
értékül egy új tömbpéldány referenciáját. A második lépés kihagyása nullreferenciát eredményez.
// declare array reference (by not specifying a capacity)
int foo[];
// we can now assign any int[] to foo
[ 1, 2, 3 ] @=> foo;
// print out 0th element
<<< foo[0] >>>;
Ez hasznos tömbparamétert váró, vagy tömböt visszaadó függvények esetén:
// our function
fun void print( int bar[] )
{
// print it
for( 0 => int i; i < bar.cap(); i++ )
<<< bar[0] >>>;
}
// we can call the function with a literal
print( [ 1, 2, 3, 4, 5 ] );
// or can we can pass a reference variable
int foo[10];
print( foo );
Mint más objektumok esetén, lehetőség van ugyanarra a tömbre több referenciát állítani.
Minden értékadás referencia értékadás, tehát a tömb elemei
nem kerülnek másolásra, csak a tömbreferencia másolódik.
// our single array
int the_array[10];
// assign reference to foo and bar
the_array => int foo[] => int bar[];
// (the_array, foo, and bar now all reference the same array)
// we change the_array and print foo...
// they reference the same array, changing one is like changing the other
5 => the_array[0];
<<< foo[0] >>>; // should be 5
Többdimenziós tömbök esetén lehetőség van a tömb résztömbjeire referenciát állítani.
A dimenziók összege ki kell hogy adja az eredeti tömb dimenzióját.
// a 3D array
int foo3D[4][4][4];
// we can make a reference to a sub-section
foo3D[2] => int bar[][];
// (note that the dimensions must add up!)