ChucK

Típusok

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:

Referencia típusok

Referencia típusok az Object leszármazottjai. Néhány beépített referencia típus:

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:

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!)