Oxygene

Utasítások, vezérlési szerkezetek



Értékadás, üres utasítás

Értékadás: változó := érték;
Üres utasítás: ;

Szekvencia

Az utasítások ; -vel elválasztva (utasítás1;utasítás2;)

Elágazások

if elágazás. Hagyományos if-then-esle elágazás. Például:

if booleanexpression then action; if booleanexpression then action1 else action2;

Ha több utasítás van akkor begin és end közé írni az utasításokat. Az else előtt nem szabad pontosvesszőt tenni ha előtte begin-end utasításblokk áll.Pl.:

if test1 then begin action1; action2; end else begin action1; action2; end;

if nem keverendő iif utasítással, ami leginkább C++ nyelvben használt :? -hez hasonlít és adott feltételtől igazságértékétől függően két adott utasítás között megfelelőt választ. Pl.:

iif(mybool,'yes','no');

case of elágazás.
Több egymást követő if-else if utasítás helyettesítésére használható. Szintaktikája:

case <ordinal | string> of <value>: <statement> <value>: <statement> else <statement> end;

Nem kötelező összes lehetséges értékre megadni utasítást, azaz nincs szükség else ágra.
Ahogyan a szintaktikájából is látható karakterláncokra is alkalmazható.

case type of. Itt a változó típusa dönti el, hogy melyik ág hajtódik végre. Szintaxis:

case <object> type of <objecttype>: <statement> <objecttype>: <statement> else <statement> end;

Ciklusok

for ciklus. Szintaxis:

for <ordinal> := <lowvalue> to <highvalue> [step <integer>] do <statement> for <ordinal> := <highvalue> downto <lowvalue> do <statement> for [each] <object> in <IEnumerableObject> do <statement> for each matching <object> in <IEnumerableObject> do <statement> for <item> in <array> do <statement>

Fontos megjegyezni, hogy Delphi-vel szemben for each ciklus futó változójának hatásköre kizárólag a ciklus magja. Ha korábban definiálva volt egy azonos nevű változó akkor az értéke nem változik meg a ciklus lefutása során. Pl.:

var x := -1; var list := new List([1, 2, 3]); for x in list do Console.Write(x + „ „) Console.Write(x);

programrész kimenete: „1 2 3 -1”

Párhuzamos for ciklus

Oxygene támogatja a párhuzamos keretrendszert (parallel framework). Így megfelelő kulcsszóval a ciklus törzsét párhuzamosan is végrehajthatjuk, de erről részletesebben a Párhuzamos végrehajtás fejezetben.

loop ciklus. Ez egy végtelen ciklus. Például:

loop begin … Console.Writeln(i); Inc(i); if i > 1000 then break; … end;

repeat ciklus: hátultesztelős ciklus. Szintaxis:

repeat // statements until SomeTest;

while ciklus. Szintaxis:

while SomeTest do begin // statements end;

Vezérlésátadó utasítások

using f := new FileStream(…) do begin … end;

Blokk utasítás

Blokk: utasítások begin és end között. Szintaxis:

begin <statement> <statement> end;

Speciális blokkutasítás még a "with" utasítás, melynek a segítségével egy csak a blokkon belül érvényes változót deklarálunk. A "with" egy speciális változata a "with match", ami abban különbözik, hogy csak akkor lép be a blokkba ha az értékadás bal oldalán szereplő kifejezés inicializálva van.

with <variable> := <object> do with <variable>: <type> := <object> do with matching <variable>: <type> := <object> do

Lekérdező kifejezések, operátorok (Query Expressions, Operators)

Lekérdező operátorok nagyrészt 3.5-ös .NET-ben bemutatott standard lekérdező operátorokon (Standard Query Operators) alapulnak, azaz System.Query-ben definiált típusokon.

Lekérdező kifejezések szintaxisa az adatbázisrendszerekben gyakran használt SQL (Structured Query Language) szintaxisára hasonlít.

Megszorítások

A where operátor adott feltétel alapján szűri az adatok szekvenciáját.

Legyen MyCustomer már létező vevő-objektumok szekvenciája. Ahhoz, hogy csak Londonból érkező vevőket tekintsünk, következőt írhatjuk:

var x := from c in MyCustomers where c.City = 'London';

„c” típusa a kontextusból elnyerhető, mert a fordító tudja, hogy „MyCustomer” típusa „sequence of customers”, így „c” típusa csakis „customer” lehet. Végrehajtás után „x” új, csak Londonból érkező vevők szekvenciáját tartalmazza.

Rendezés

Order by operátor segítségével egy vagy több kulcs alapján rendezhetjük egy szekvencia elemeit. Például ahhoz, hogy az előző példában kapott eredmény rendezett legyen a vevők neve alapján, következőt írhatunk:

var x := from c in MyCustomers where c.City = 'London' order by c.Name;

Értelemszerűen a „where” elhagyható, nélküle a vevők teljes listáját rendeznénk név szerint.

Továbbra alapértelmezetten növekvő sorrend mellett rendezhetünk csökkenő sorrendben is vagy explicit módon írhatjuk ki, hogy növekvő sorrendben rendezünk:

... order by c.Name asc, c.DateOfBirth desc;

itt asc növekvő, desc csökkenő sorrendet jelent.

Reverse operátor megfordítja a szekvencia sorrendjét. Ez az operátor nem kap paramétert, és akárhol használható a lekérdezésben. Ha reverse után is vannak operátorok, akkor azok forrdított sorrendben lesznek alkalmazva.

Projekció

Select utasítással megadhatjuk, hogy az eredi szekvenciát alkotó adatok mely részelemeit szeretnénk felhasználni új szekvencia adatainak generálásakor, illetve megadhatjuk a generálásra vonatkozó szabályokat is. Például:

var list := from c in MyCustomers select (c.Name, c.City, DateTime.Now-c.DateOfBirth as Age);

Ez a lekérdezés új, névtelen osztály típusú szekvenciát eredményez, mely csak Name,City és Age mezőket tartalmaz. Az utóbbi mező eredeti osztály két mezejéből lett generálva.

Adatok egyesítésé

A legkomplexebb operátor a join operátor. Segítségével több különálló szekvenciából képezhetünk egy új szekvenciát.

Például tegyünk fel, hogy van egy Countries nevű szekvenciánk, mely városokra vonatkozó információkat tartalmaz. Például azt, hogy mi a szokásos üdvözlési forma egy-egy városban. Az előző példákban használt Customers táblából könnyen generálhatunk üdvözlő szöveget:

var greet := from cust in MyCustomers join cntry in Countries on cust.Country equals cntry.Name select cntry.Greeting + ' ' + cust.Name;

Az új szekvencia elemei következőek lehetnek: "Hello Paul", "Bonjour, Jean-Pierre", stb..

Az Oxygene nyelv arra is ad lehetőséget, hogy a lekérdező kifejezéseket for each ciklusokkal használjuk. Az eredeti szintaxis használatával következőképpen írhatjuk le egy for each ciklust:

for each c1 in from c2 in Customers where c2.Age > 30 do …

Ám a ciklus két változót is használ annak nagy szüksége nélkül, így redundánsnak tűnik. Ennek kiküszöbölése érekében következőképpen is írhatjuk a lekérdező kifejezést for each ciklusban:

for each from c in Customers where c.Age > 30 do …

Itt c egyszerre a lekérdezés változója és a ciklus „futó” változója. Értelemszerűen akármilyen bonyolult lekérdező kifejezés szerepelhet a ciklusban. Emellett into használatával deklarálhatjuk ciklus törzsében használható változókat:

for each from c in Customers where c.Age > 30 select c.FirstName+' '+c.LastName into n do ...

Lambda kifejezések

Az előbb említett programkonstrukciók mellett Oxygene támogatja az úgy nevezett lambda kifejezéseket. Egy ilyen kifejezés legkönnyebben egy szekvenciát másikba elemenként transzformáló függvényként képzelhető el.

Technikailag egy lambda kifejezés nem más mint egy névtelen metódus, így

c -> c.Name

ekvivalens a következővel:

method (c: ''type1''): ''type2''; begin result := c.Name; end;

azzal a kivétellel, hogy lambda kifejezés esetén a type1 és type2 típusa a kontextusból kikövetkeztethető.

Lekérdezési operátorokkal együtt használva lambda kifejezések néhány szempontból előnyösebbek a névtelen metódusoknál:

A legfontosabb mégis, hogy kontextustól függően egy lambda kifejezés gépi kóddá fordítható vagy úgy nevezett kifejezésfává (Expression tree) alakítható és távoli gépen futtatható.