Delphi (programmeringsspråk)

Den aktuella versionen av sidan har ännu inte granskats av erfarna bidragsgivare och kan skilja sig väsentligt från versionen som granskades den 8 januari 2020; kontroller kräver 103 redigeringar .
Delphi
Språkklass imperativ , strukturerad , objektorienterad , komponentorienterad , hög nivå
Framträdde i 1986  ( 1986 )
Författare Anders Hejlsberg
Filtillägg _ .pas, .dpr, .dpk, .pp, .dproj, .dfm, .fmx, .bpl
Släpp Delphi 11.1 Alexandria [1]  (15 mars 2022 ) ( 2022-03-15 )
Typ system statisk , stark
Stora implementeringar Borland/Inprise/Codegear/Embarcadero Delphi ; Borland Kylix ; gratis pascal
Blivit påverkad Objekt Pascal , C++
påverkas C# , Java [1]
Hemsida embarcadero.com/ru/produ...
Plattform x86, x64, ARM
OS Windows , macOS , iOS , Android , Linux

Delphi (Delphi, uttalas /ˈdɘlˌfi:/ [2] ) är ett imperativt, strukturerat , objektorienterat programmeringsspråkhög nivå med stark statisk typning av variabler. Det huvudsakliga användningsområdet är att skriva applikationsprogram.

Detta programmeringsspråk är en dialekt av Object Pascal-språket . Object Pascal refererade ursprungligen till ett något annorlunda språk som utvecklades hos Apple 1986 av Larry Teslers grupp [3] . Men från och med Delphi 7 [4] började Borlands vitböcker använda namnet Delphi för att hänvisa till språket som tidigare var känt som Object Pascal .

Målplattform

Ursprungligen var utvecklingsmiljön Delphi uteslutande avsedd för utveckling av Microsoft Windows-applikationer , sedan implementerades en variant för Linux- plattformar (märkt som Kylix ), men efter lanseringen av Kylix 3 2002 avbröts utvecklingen och stöd för Microsoft .NET tillkännagavs snart . som i sin tur avbröts med lanseringen av Delphi 2007.

För närvarande, tillsammans med stöd för utveckling av 32- och 64-bitarsprogram för Windows, är det möjligt att skapa applikationer för Apple macOS (börjar med Embarcadero Delphi XE2), iOS (inklusive en simulator, med början XE4 med sin egen kompilator), Google Android (som börjar med Delphi XE5) [5] , samt Linux Server x64 (med start från version 10.2 Tokyo).

En oberoende tredjepartsimplementering av utvecklingsmiljön av Lazarus - projektet ( Free Pascal , när den kompileras i Delphi-kompatibilitetsläge) gör att den kan användas för att bygga Delphi-applikationer för plattformar som Linux , macOS och Windows CE .

Det har också gjorts försök att använda språket i GNU- projekt (t.ex. Notepad GNU ) och att skriva en kompilator för GCC ( GNU Pascal ).

Används för att skriva IIS-internettjänster.

Filosofi och skillnader från populära tillämpade programmeringsspråk

När man skapade språket (och här den kvalitativa skillnaden från C-språket) var uppgiften inte att säkerställa maximal prestanda för den körbara koden eller kortfattad källkod för att spara RAM. Inledningsvis fokuserade språket på harmoni och hög läsbarhet, eftersom det var tänkt att lära ut disciplinen programmering. Denna initiala slankhet senare, både när hårdvaran växte och som ett resultat av uppkomsten av nya paradigm, gjorde det lättare att utöka språket med nya konstruktioner.

Alltså har komplexiteten hos objekt C++, i jämförelse med C, vuxit mycket markant och gjort det svårt att studera det som det första programmeringsspråket, vilket inte kan sägas om Object Pascal i förhållande till Pascal.

Följande är några av skillnaderna mellan Delphis syntaxkonstruktioner och familjen av C-liknande språk (C/C++/Java/C#):

program Projekt32 ; {$APPTYPE KONSOL} {$R *.res} använder System . Sysutils ; börja försök { TODO -oUser -cConsole Main: Insert code here } förutom E : Exception do Writeln ( E . ClassName , ': ' , E . Message ) ; slut ; slut . I C-liknande programmeringsspråk mainanvänds vanligtvis en global funktion eller statisk metod med ett namn och en viss lista med parametrar som indata, och en sådan funktion kan finnas i vilken som helst av projektets källfiler.
  • I Delphi läses identifierare för typer, variabler och nyckelord skiftlägesokänsliga : till exempel är en identifierare SomeVarhelt ekvivalent med somevar. Skiftlägeskänsliga identifierare i början av datoråldern påskyndade kompileringsprocessen och tillät också användningen av mycket korta namn, ibland skilde sig endast i skiftläge.
Och även om båda dessa metoder vid det här laget - användningen av flera identifierare som endast skiljer sig åt i fall, såväl som deras överdrivna koncisa, är fördömda och inte rekommenderas för användning, kommer nästan alla språk från C - C + +, Java, C # - är skiftlägeskänsliga , vilket å ena sidan kräver ganska mycket noggrannhet i att deklarera och använda identifierare, och å andra sidan tvingar det dig att skriva mer strikt kod när varje variabel har en väldefinierat namn (variationer i skiftlägen kan orsaka förvirring och fel).
  • I Delphi, i .pas-källfilerna (som i regel innehåller programmets huvuddel), introduceras en strikt uppdelning i gränssnittssektionen och implementeringssektionen på språknivå. Gränssnittsdelen innehåller endast typ- och metoddeklarationer medan implementeringskoden i gränssnittsdelen inte är tillåten på kompileringsnivån. En liknande separation är också karakteristisk för C/C++-språken, där, inom ramen för kultur- och programmeringsparadigmet, en separation introduceras i header- och faktiska implementeringsfiler, men en sådan separation tillhandahålls inte på språket eller kompilatorn nivå.
I C# och Java är denna separation helt förlorad - implementeringen av en metod följer som regel omedelbart efter dess deklaration. Inkapsling tillhandahålls endast genom att metoden tillhör en eller annan omfattning. Specialverktyg används för att endast se gränssnittsdelen av källkodsmodulen.
  • I Delphi är en metod eller funktion tydligt definierad av de reserverade nyckelorden procedureeller function, medan i C-liknande språk görs skillnaden av ett nyckelord som anger typen av returvärde://Delphi - proceduren DoSomething ( aParam : Heltal ) ; //returerar inte en värdefunktion Calculate ( aParam1 , aParam2 : Integer ) : Integer ; //returerar ett heltalsresultat //C# void DoSomething ( int aParam ); // returnerar inte ett värde { // code } int Calculate ( int aParam1 , aParam2 ); // returnerar ett heltalsresultat { // code }
Desto svårare i C#/C++ är sådana konstruktioner som att deklarera typen "pekare till metod"://C++: pCalc-typdeklaration, en pekare till en medlemsfunktion som tar två heltalsparametrar och returnerar ett heltalsresultat typedef int ( TSomeClass ::* pCalc )( int , int ); I exemplet ovan skiljer sig typdeklarationen från variabeldeklarationen med nyckelordet typedef, typnamnet, pCalc, anges i mitten av uttrycket, inom parentes.//C#: pCalc-typdeklaration, en pekare till en medlemsfunktion som tar två heltalsparametrar och returnerar ett heltalsresultat offentligt delegat int pCalc ( int aParam1 , int aParam2 ); I exemplet ovan skiljer sig typdeklarationen från variabeldeklarationen med ett speciellt nyckelord delegate, typnamnet anges i mitten av uttrycket.//Delphi typ pCalc = funktion ( aParam1 , aParam2 : Heltal ) : Heltal för objekt ; I exemplet ovan skiljer sig typdeklarationen från deklarationen av en variabel med ett speciellt nyckelord type, användningen av ett likhetstecken (i fallet med en variabel används kolon), typnamnet kommer omedelbart efter nyckelordet.
  • I Delphi är början och slutet av ett programblock markerade med nyckelorden beginoch end, medan i C-liknande programmeringsspråk används lockiga klammerparenteser för detta ändamål: {}. Därmed kanske Delphi uppnår bättre kodläsbarhet för synskadade. Å andra sidan kan lockiga hängslen vara mer visuellt intuitiva och fungera som ett piktogram .//C# if ( bVal ) { // kod som består av flera instruktioner } if ( bVal2 ) /* kod som består av en instruktion */ ;
I exemplet ovan betecknar lockiga hängslen ett sammansatt uttalande, det vill säga ett block av uttalanden. Eftersom ett uttryck utan klammerparenteser är tillåtet i ett grenkommando för en enskild sats krävs parenteser för ett villkorligt uttryck . I komplexa villkorliga uttryck kan antalet kapslade parenteser vara stort.//Delphi if bVal then start // multi-instruction code end ; om bVal2 (* enkel instruktionskod *) ; I Delphi separeras alltid det villkorliga uttrycket från nästa påstående med nyckelordet then, vilket eliminerar behovet av att omge villkoret inom parentes.
  • I C-liknande språk, för denna separation, är slingan betingad inom parentes:while ( condition ) { // loop med "precondition" // loop body }; gör { // body of another loop } while ( villkor2 ); // slutet av slingan med ett "postcondition", kroppen exekveras minst en gång
I Delphi skiljer sig loopar med ett förutsättning och ett postvillkor mer: slutet av en loop med ett postvillkor är svårare att förväxla med början av en loop med ett förutsättning. Men ibland kan en sådan distinktion orsaka förvirring (man måste komma ihåg att utgångsvillkoretuntil anges i slingan ).while condition do start //villkoret för att fortsätta loopen är sanningen i uttrycket efter ordet while, som C/C# //loop body end ; upprepa //början av loop med postcondition //loop body tills inte condition2 ; //sanningen i uttrycket efter ordet till är villkoret för EXIT från slingan, i motsats till C/C#
  • I Delphi betecknas operationen att tilldela ett värde till en variabel med ett kolon med likhetstecken, :=, som är lånat från matematisk notation. Ett likhetstecken utan kolon är en likhetstesteoperator som returnerar ett booleskt värde. I motsats till C-liknande språk är tilldelningsoperatorn ett enda likhetstecken, och likhetstestet är ett dubbeltecken, ==. På grund av det faktum att uppgiften i dessa programmeringsspråk bara är ett uttryck som returnerar värdet på variabeln till vänster, är följande misstag som inte är uppenbara för en nybörjare inte så sällsynta:// C++ int iVal = 12 ; while ( iVal = 1 ) { // enligt programmerarens avsikt ska denna loopkropp inte exekveras om iVal har ett annat värde än ett vid ingången // men som ett resultat av en felaktig ersättning av ==-tecknet med ett enda =, kommer iVal att vara tilldelas värdet 1, och slingan kommer att vara oändlig }
I Delphi är ett sådant fel omöjligt, om så bara för att uppgiften på detta språk är en operation som inte returnerar ett värde.
  • I Delphi är objekt- och objektorienterad programmering, även om den uppmuntras, inte den enda möjliga. Så det är tillåtet (till skillnad från C#) att deklarera och använda globala eller statiska funktioner och variabler.
C#-språket tvingas vara objekt. Globala, utan referens till en klass, funktioner är förbjudna. Värdetyper, som structs struct, ärvs från den generiska C#-typen, även om de själva inte kan ärvas (det vill säga, struct-arv är inte tillåtet i C#). Förekomster av C#-klasser är dock implicita referenstyper, precis som i Delphi. Eftersom systemanrop i Windows (som faktiskt i POSIX-system som Linux, Mac OS) formellt är icke-objekt, är interaktion av C #-kod med dem svårt även utan att ta hänsyn till det olika paradigmet för att hantera livslängden för variabler i minnet . Delphi har inga sådana begränsningar. Trots detta objektcentrerade paradigm saknar C# konceptet med en virtuell konstruktor, det vill säga att skapa en instans av en klass vars exakta typ inte är känd vid kompileringstidpunkten, men endast basklassen för den instansen är känd. Delvis kan denna nackdel kompenseras genom att använda gränssnitt eller reflektion, men sådana lösningar är inte standard för språket.typ TAnimal = klass abstrakt skyddad FPersonalName : string ; public constructor Create ( const PersonalName : string ) ; virtuell ; abstrakt ; function GetSpecieName : string ; virtuell ; abstrakt ; // returnerar den biologiska arten av djuregenskapen Namn : sträng läs FPersonalName ; slut ; TAnimalClass = klass av TAnimal ; // metaklass som kan referera till vilken klass som helst som ärver från TAnimal ... function CreateAnimal ( const FactAnimalClass : TAnimalClass ; const Namn : string ) : TAnimal ; börja Resultat := FactAnimalClass . Skapa ( namn ) ; // funktionen vet inte vilken typ av djur som kommer att skapas, även om "smeknamnet" är känt. Den konkreta implementeringen av vyn är dold. slut ; Dessutom, till skillnad från C# och C++, där anropet till basklassens konstruktor nödvändigtvis görs innan kroppen av den ärvda klasskonstruktorn, görs detta anrop explicit i Delphi. Det kan alltså skjutas upp eller utelämnas helt för särskilda ändamål. Uppenbarligen, till skillnad från C#, är det möjligt att kontrollera undantag i baskonstruktörer.
  • För den mest flexibla och effektiva implementeringen av det objektorienterade tillvägagångssättet introducerade Delphi två polymorfa anropsmekanismer: klassisk virtuell och dynamisk : om i fallet med ett klassiskt virtuellt anrop kommer adresserna till alla virtuella funktioner att finnas i tabellen över virtuella metoder för varje klass, i fallet med ett dynamiskt anrop finns en pekare till en metod endast i tabellen för den klass där den definierades eller åsidosattes.
För att dynamiskt anropa från klass D en metod av klass A omdefinierad i B, kommer det att vara nödvändigt att söka i metodtabellerna för klasserna D, A och B. Denna optimering syftar till att minska storleken på det statiska minnet som upptas av metodtabeller. Besparingarna kan vara betydande för långa klasshierarkier med ett mycket stort antal virtuella metoder. I C-liknande språk används inte dynamiska polymorfa anrop.
  • Till skillnad från C# tillåter Delphi-språket skapande (initiering) av en instans av en klass som innehåller abstrakta (som inte har någon implementering) metoder. För att utesluta möjligheten att skapa en instans av en klass räcker det inte att deklarera abstrakta metoder i den. Det abstrakta nyckelordet måste användas i klassdeklarationen. För närvarande anses klasser som har abstrakta metoder (till skillnad från tidiga Delphi-implementationer) inte vara abstrakta. Med hjälp av den virtuella funktionsmekanismen avgör koden för en basklass som har abstrakta metoder vid körning om en viss abstrakt metod åsidosätts i den faktiska instansen av klassen och, beroende på detta, anropar den åsidosatta metoden eller kastar ett EAbstractError-undantag.
Delphi tillåter också att alla konkreta virtuella metoder för en basklass åsidosätts av en abstrakt i en underklass:typ TMyBase = klass ( TObject ) funktion A : heltal ; virtuell ; // metod A har en implementerad kropp i implementeringsslutsektionen ; TMyDerived = klass ( TMyBase ) funktion A : heltal ; åsidosätta ; abstrakt ; // metoden åsidosätts som abstrakt, har ingen kropp, // och åsidosätter (döljer) samtidigt den som är implementerad i basklassens slut ; procedur Test ; var m : TMyBase ; börja m := TMyDerived . skapa ; // vi har skapat en klass med en abstrakt metod m . A ; // anropet till A är polymorft och vi får ett EAbstractError när vi försöker köra den abstrakta metoden end ;
  • Till skillnad från C++ har C#-språket konceptet med klassegenskaper som är ärvt från Delphi: pseudofält, som i vissa fall mer intuitivt, jämfört med metoder, kan reflektera och även ändra ett objekts tillstånd.public class Date { //det här exemplet är hämtat från [http://msdn.microsoft.com/en-us/library/w86s7x04.aspx msdn] private int month = 7 ; // stödbutik public int Month { get { return month ; } set { if (( värde > 0 ) && ( värde < 13 )) { månad = värde ; } } //set } //prop } //klass
En liknande källkod i Delphi kan se ut så här:typ TDate = klass privat FMonth : Heltal ; skyddad procedur SetMonth ( const Value : Integer ) ; // implementering i implementeringssektionen public property Month : Heltal läs FMonth skriv SetMonth ; slut ; Innan vi går vidare till en jämförelse av språkimplementeringen av egenskaper, noterar vi att en jämförelse av dessa två exempel tydligt visar att språket C # framkallar, för det första, missbruk av lockiga hängslen (vilket inte är så skrämmande med tanke på hur kortfattat deras skrivning), och, för det andra, de obligatoriska åtkomstspecifikationerna för högen för varje klassmedlem; i Delphi (som i C++), när en specificator har deklarerats, gäller den för alla efterföljande medlemmar. Dessutom, om det i Delphi är möjligt att binda en egenskap till ett fältvärde, är de i C# alltid försedda med accessormetoder med hjälp av sammansatta kommandoparenteser (förutom för automatiska egenskaper). Dessa metoder, till skillnad från i Delphi, kan inte deklareras som virtuella, och de kan inte heller anropas direkt. En accessor i C# refererar alltid till en och endast en egenskap, medan i Delphi detta påstående i allmänhet inte är sant. Dessutom kan samma metod användas för att implementera åtkomst till väsentligt olika egenskaper:typ TRectangle = klass privat FCordinater : array [ 0..3 ] av Longint ; _ _ funktion GetCoordinate ( Index : Heltal ) : Longint ; procedure SetCoordinate ( Index : Heltal ; Värde : Longint ) ; public property Vänster : Longint index 0 läs GetCoordinate skriv SetCoordinate ; egenskap Top : Longint index 1 läs GetCoordinate skriv SetCoordinate ; egenskap Rätt : Longint index 2 läs GetCoordinate skriv SetCoordinate ; egenskap Botten : Longint index 3 läs GetCoordinate skriv SetCoordinate ; egenskap Koordinater [ Index : Heltal ] : Longint läs GetCoordinate skriv SetCoordinate ; slut ; Både Delphi och C# tillåter användning av indexerade egenskaper: i det här fallet liknar syntaxen för att komma åt en sådan egenskap som att komma åt ett arrayelement. Men även om antalet indexerade egenskaper i Delphi, såväl som antalet indexerare, kan vara godtyckliga, gäller i C# indexeraren endast för en speciell standardegenskap. I Delphi kan inte bara en standardegenskap vara indexerbar, den kan också överbelastas av en indexeringstyp:TMyObject = klassskyddad funktion getStr ( Namn : sträng ) : sträng ; _ virtuell ; funktion getStrByIx ( Index : Heltal ) : sträng ; virtuell ; funktion getBy2Indicies ( X , Y : Heltal ) : sträng ; virtuell ; public property Värde [ Namn : sträng ] : sträng läs getStr ; standard ; egenskap Värde [ Index : Heltal ] : sträng läs getStrByIx ; standard ; egenskap Värde [ X , Y : Heltal ] : sträng läs getBy2Indicies ; standard ; //nummer slut ;
  • Språken Java och C# designades ursprungligen för att skriva program som körs i en hanterad miljö där miljön hanterar objektens livslängd: så manuell minneshantering är inte tillåten. Bekvämligheten och säkerheten med detta tillvägagångssätt har en negativ inverkan på prestandan.
För- och nackdelar med sophämtning

.NET- och Java-plattformarna har avsevärt förenklat utvecklingen av program genom att introducera en "sopsamlare", som gör att programmeraren inte kan oroa sig för att frigöra minnet som upptas av objekt som har gått utanför räckvidden för den pågående programkoden. Detta minskade å ena sidan avsevärt problemet med så kallade "minnesläckor" (när data som redan är onödiga och oåtkomliga på grund av förlusten av adressen tar upp RAM), men å andra sidan krävde det plattform för att implementera en komplex och resurskrävande "sopsamlingsalgoritm" - som traditionellt implementeras som att hitta nåbara objekt och släppa resten. I praktiken, för att utföra en uttömmande analys av objekts nåbarhet, avbryter sophämtaren vid vissa tidpunkter programmet (alla dess trådar), vilket leder till en kortvarig förlust av lyhördhet. Frekvensen och varaktigheten av sådana stopp beror direkt på mängden tillgängligt RAM (så länge det finns ledigt minne försöker sophämtaren att inte utföra blockeringsanalys), såväl som på antalet objekt som är involverade i programmet (då, det är bättre att ha några "stora" föremål än många - små).

Situationen förvärras i takt med att antalet inblandade trådar i programmet växer, eftersom en uttömmande nåbarhetsanalys kräver ett fullständigt stopp. Således gav den uppenbara fördelen - att lösa problemet med "minnesläckor" och i allmänhet automatisk hantering av objekts livslängd - upphov till det implicita problemet med skalning och prestanda "fel". Detta problem är subtilt i enkla program, men i takt med att komplexiteten och storleken på kodbasen växer blir det mer och mer akut - det vill säga i det sista utvecklingsskedet. Komplexa mjukvarusystem har som regel referens- och lyhördhetskrav i realtid.

Närmare bestämt, när sopsamlaren har 5 gånger mer minne än den behöver, är dess prestanda lika med eller något bättre än direkt minneshantering. Däremot försämras sopsamlarens prestanda snabbt när den behöver arbeta med små höfter. Med 3 storlekar av erforderligt minne är det i genomsnitt 17 % långsammare, och med 2 storlekar är det 70 % långsammare. Även sopsamlaren är mer benägen att söka om minnet är defragmenterat. Under sådana förhållanden är alla sophämtare vi har testat en storleksordning långsammare än direkt minneshantering.Drew Crawford - Varför mobila webbappar är långsamma

Försök att minska omkostnaderna för sophämtning kan leda till betydande snedvridning av programmeringsstilen [6] [7] .

Det finns ingen automatisk minneshantering i Delphi: (i klassiska språkkompilatorer) skapas och raderas klassinstanser manuellt, medan för vissa typer - gränssnitt, strängar och dynamiska arrayer, används referensräknemekanismen. Inget av dessa tillvägagångssätt, generellt sett, garanterar frånvaron av minnesläckor, men å andra sidan är problemet med lyhördhet inte relevant, tiden för minneshantering är liten och, ännu viktigare, uppenbar. Dessutom, i frånvaro av läckor, är den totala mängden använt RAM-minne betydligt mindre än liknande applikationer som är beroende av sophämtaren.

Språkets historia

Objekt Pascal är resultatet av utvecklingen av Turbo Pascal- språket , som i sin tur utvecklades från Pascal- språket . Pascal var ett helt processuellt språk , Turbo Pascal, från och med version 5.5, lade till objektorienterade egenskaper till Pascal och dynamisk datatypsidentifiering till Object Pascal med möjligheten att komma åt klassmetadata (det vill säga att beskriva klasser och deras medlemmar) i kompilerad kod, även kallad introspektion  - denna teknik kallades RTTI . Eftersom alla klasser ärver funktionerna i basklassen TObject, kan valfri pekare till ett objekt konverteras till det, varefter ClassType-metoden och TypeInfo-funktionen kan användas, vilket ger introspektion.

En utmärkande egenskap hos Object Pascal från C++ är också att objekt som standard finns i dynamiskt minne. Du kan dock åsidosätta de virtuella metoderna NewInstance och FreeInstance för TObject-klassen. Således kan absolut vilken klass som helst uppfylla "önskan" "var jag vill - där ska jag ligga." Följaktligen är "multi-heaping" organiserad.

Objekt Pascal (Delphi) är resultatet av en funktionell förlängning av Turbo Pascal [8] .

Delphi hade en enorm inverkan på konceptet med C# -språket för .NET- plattformen . Många av dess element och konceptuella lösningar har införlivats i C#. En av anledningarna är överlåtelsen av Anders Hejlsberg , en av de ledande utvecklarna av Delphi, från Borland Ltd. på Microsoft Corp.

  • Version 8 kan generera bytekod exklusivt för .NET-plattformen. Detta är den första miljön som fokuserar på utveckling av flerspråkiga applikationer (endast för .NET-plattformen);
  • Efterföljande versioner (anges av utgivningsår, snarare än serienummer, vilket var fallet tidigare) kan skapa både Win32-applikationer och bytekod för .NET-plattformen.

Delphi för .NET  är en Delphi- utvecklingsmiljö , såväl som språket Delphi (Object Pascal), fokuserat på att utveckla applikationer för .NET.

Den första versionen av en fullfjädrad Delphi-utvecklingsmiljö för .NET var Delphi 8. Den tillät endast att skriva applikationer för .NET. Delphi 2006 stöder MDA-teknik med ECO (Enterprise Core Objects) version 3.0.

I mars 2006 beslutade Borland att stoppa ytterligare förbättringar av de integrerade utvecklingsmiljöerna JBuilder , Delphi och C ++ Builder på grund av olönsamheten i denna inriktning. Det var planerat att sälja företagets IDE-sektor. En grupp anhängare av fri programvara organiserade en insamling för att köpa rättigheterna till utvecklingsmiljön och kompilatorn från Borland [9] .

I november samma år togs dock beslutet att inte sälja IDE-verksamheten. Ändå kommer utvecklingen av IDE-produkter nu att skötas av ett nytt företag - CodeGear, som kommer att vara helt ekonomiskt kontrollerat av Borland.

I augusti 2006 släppte Borland en lättversion av RAD Studio som heter Turbo: Turbo Delphi (för Win32 och .NET), Turbo C#, Turbo C++.

I mars 2008 tillkännagavs slutet på utvecklingen av denna produktlinje.

I mars 2007 nöjde CodeGear användarna med en uppdaterad linje av Delphi 2007 för Win32-produkter och lanseringen av en helt ny Delphi 2007 för PHP-produkt.

I juni 2007 presenterade CodeGear sina planer för framtiden, det vill säga publicerade den så kallade färdplanen [10] .

Den 25 augusti 2008 publicerade Embarcadero, den nya ägaren av CodeGear, ett pressmeddelande om Delphi för Win32 2009 [11] . Versionen förde med sig många innovationer till språket, såsom [12] :

  • Som standard fullt Unicode- stöd i alla delar av språket, VCL och RTL; ersätta anrop till alla Windows API-funktioner med Unicode-motsvarigheter (det vill säga MessageBox anropar MessageBoxW, inte MessageBoxA).
  • Generiska typer , de är också generiska .
  • Anonyma metoder .
  • Nytt kompilatordirektiv $POINTERMATH [ON|OFF].
  • Exit-funktionen kan nu acceptera parametrar beroende på typen av funktion.

Delphi XE2 släpptes 2011 och lade till en Win64- kompilator och korskompilering för Apples operativsystem (MacOS X, iOS).

Delphi XE5 släpptes 2013 och tillhandahöll korskompilering av applikationer för ARM/Android-enheter.

Kompilatorer

  • Embarcadero Delphi (tidigare CodeGear Delphi och Borland Delphi) är förmodligen den mest kända kompilatorn som är efterföljaren till Borland Pascal och Turbo Pascal . Används av Win16 (Delphi 1), Win32 (Delphi 2 och senare), Win64 (Delphi 16 (XE2) och senare), och .NET 1.x, 2.0 (Delphi 8, Delphi 2005-Delphi 2007). .NET-stöd kopplades sedan av till en separat produkt känd som (Delphi-inkompatibel) Oxygene .
  • Free Pascal (FPC) är en gratis Object Pascal-kompilator som stöder olika Pascal-dialekter, inklusive Turbo Pascal (med vissa varningar), Delphi och inhemska dialekter. För närvarande kan FPC generera kod för x86 , x86-64 , PowerPC , SPARC och ARM-processorer , såväl som för olika operativsystem, inklusive Microsoft Windows , Linux , FreeBSD , Mac OS . Det finns flera mjukvaruutvecklingsmiljöer för FPC (en av de mest kända representanterna är Lazarus ).
  • GNU Pascal (en separat utvecklad version från GCC ). Den syftar inte till att fortsätta serien av Delphi-dialekter som en del av Pascal, men innehåller ändå Borland Pascal-kompatibilitetsläget och är mycket långsam för att ta emot Delphi-språkkomponenter. Inte lämplig för att kompilera stora projekt som innehåller Delphi-kod, men de flesta operativsystem och arkitekturer stöder det.
  • Oxygene (tidigare känt som Chrome ) är en begränsad Delphi-kompatibel språkkompilator som är integrerad i Microsoft Visual Studio . Finns även tillgänglig som en gratis CLI kommandoradskompilator . Använder .NET och monoplattformar. Såldes tidigare under varumärket Embarcadero Delphi Prism.
  • MIDletPascal  är ett programmeringsspråk med en Delphi-liknande syntax och en kompilator med samma namn som konverterar källkod till kompakt och snabb Java-bytekod .
  • PocketStudio  är en Pascal-baserad IDE för Palm OS .
  • Virtual Pascal  - Gratis kompilator och text-IDE för Win32, OS/2 och Linux. På den tiden mycket snabb och mycket kompatibel (delphi 5-konstruktioner stöds delvis). Utåt sett är den väldigt lik Borland Pascal 7-textmiljön, även om det till exempel inte finns någon grafik kompatibel med den. Utvecklingen avslutades dock 2004 och källkoden var inte öppen. Sedan dess har FPC gått mycket längre och är generellt sett bättre för programmering. Ändå är VP fortfarande ett mycket bra alternativ för en snabb ersättning för ännu mer föråldrade versioner av Borland Pascal för skola / institut, givet inbyggt arbete i Win32 utan problem med ryska kodningar.

Syntax för språket

Typsystemet

Typsystemet i Delphi är strikt , statiskt .

En kort lista över typer som stöds

Följande datatyper stöds :

  • heltal, signerad och osignerad: Byte, Shortint, Word, Smallint, Cardinal,Integer, UInt64, Int64
  • användardefinierade enumtyper
  • real types Single, Double, Extended (endast x86-32, på Win64 Extended = Double), ärvd Real48-typ, arbetar i heltalsemuleringsläge. Typen Currencyär verklig med fast precision.
  • rader. Typen string allokeras automatiskt i minnet, med referensräkning och Copy-On-Write-paradigmet. I senare versioner av Delphi är tecken dubbelbyte, Unicode-kompatibla. AnsiString är en liknande implementering för strängar med en teckenbredd på en byte. Sådana strängar innehåller information om kodningen i servicefältet. Windows-kompilatorer från tidigare versioner har en typ WideStringsom är helt kompatibel med typen BSTRi Component Object Model . Det är också tillåtet att använda strängar med en fast längd som inte överstiger 255 enkelbyte-tecken. Primitiva strängtyper är tillåtna, C: stil PCharochPWideChar
  • matriser. Endimensionell, flerdimensionell fast längd, samt liknande dynamik, med referensräkning.
  • uppsättningar som består av element av typen uppräkning. Den maximala storleken på en sådan uppräkning är 256 element.
  • Inlägg . Strukturell (värde) typ utan arvsstöd. Från och med Delphi 2006 har stöd för inkapsling, metoder och egenskaper lagts till. Operatör överbelastning. Från och med Delphi 10.3 Rio har möjligheten att skapa konstruktörer för skrivning lagts till.
  • Klasser och generiska klasser (generika). En implicit referenstyp. Stöd för inkapsling, nedärvning, polymorfism, inklusive virtuella konstruktörer, attribut, generiska parametrar för en klass och individuella metoder och metodsändning per index. En klass kan implementera ett eller flera gränssnitt, inklusive indirekt genom att delegera implementeringen av ett gränssnitt till en egenskap eller ett fält. Flera arv stöds inte.
  • Pekare till funktioner och metoder, samt pekare till anonyma funktioner.
  • Typer är metaklasser som innehåller en pekare till typen av ett objekt (men inte själva objektet). Främst introducerat för att implementera virtuella konstruktörer och automatisk serialisering.
  • gränssnitt. COM-kompatibel (på Windows-kompilatorn), ärvd från samma förfader. Flera arv stöds inte.
  • Dispinterfaces, för att arbeta med IDispatch-gränssnitt i sen bindningsläge.
  • Varianttyper Variant ochOleVariant — typ med dynamisk typning.
  • Gamla föremål underhållna för kompatibilitet med Turbo Pascal. Till skillnad från en instans av en klass, kan ett objekt allokeras på stacken, eller statiskt. .

Operatörer

Lista över operatorer separerade med ett mellanslag::= + — * / div mod not and or with xor shl shr ^ = <> >= <= < > @ in is as

Kort lista över operatörer
  • Aritmetik: + — * / div modAddition, subtraktion, multiplikation, division (som ger ett verkligt resultat), heltalsdivision, restextraktion.

Returtypen skiljer mellan heltalsdelningsoperatorerna ( divoch mod) och operatorn /. Det senare, applicerat på både heltals- och reella operander, resulterar alltid i en riktig typ. Adderingsoperatorn +används också för strängsammansättning (när de inbyggda strängtyperna används).

  • Binär /logisk: not and or xorInversion (negation), "OCH", "ELLER", Exklusivt "ELLER". Typen av operation (binär eller logisk) beror på typen av den första operanden.

Bitoperatorer av heltalstyper inkluderar också shl, shr - shift-operatorer, som i betydelse motsvarar samma namngivna kommandon för Intel x86-processorer.

  • Ordinaloperatorer (jämförelseoperatorer) = <> > < >= <= — likheter, ojämlikheter (motsvarar operatorn !=i C-liknande språk), större än, mindre än, inte mindre, inte mer — gäller för alla ordinala och reella typer och returnerar ett värde på typboolean
  • Uppsättningsoperatorer inkluderar + - * in addition, subtraktion, set skärningspunkt och förekomsttestoperatorn, som används för att manipulera den inbyggda uppsättningstypen. De tre första returnerar typen av uppsättningen, den sista returnerar den booleska typen.
Ett exempel på användning av in-operatorn typ TDayOfWeek = ( måndag , tisdag , onsdag , torsdag , fredag , lördag , söndag ) ; //set enum typ TDays = uppsättning av TDayOfWeek ; //uppsättningstypen är inställd var dag : TDayOfWeek ; dagar : TDagar ; isMyDay : Boolean ; start days := [ söndag , tisdag , lördag ] ; dag := måndag ; isMyDay := dag i dagar ; // in-operatorn returnerar ett booleskt värde, som tar som den första operanden ett värde av typen "set element" och som den andra operanden ett värde av typen "set" end ;
  • Typgjutningsoperatörer () as is - ovillkorlig gjutning, säker gjutning av objekt- och gränssnittstyper och typmedlemskapstestoperatör (returnerar ett booleskt värde). Ovillkorlig (osäker) gjutning används i en funktionell stil (typidentifierare skrivs till vänster, uttrycket cast till det skrivs inom parentes till höger) och tillämpas på ordningsföljd, reell, struktur, referens, strängtyper. Samtidigt, för referenstyper (inklusive implicit referens) finns det ingen faktisk roll, utan bara en ny tolkning av samma data.

Operatörerna asoch isgäller för typer som tillåter polymorft beteende—klassinstanser och gränssnitt. Det första resulterar i en säker (i betydelsen omöjlighet att feltolka) typkonvertering, och det andra testet stöds av en instans av en klass eller gränssnitt för någon klass eller gränssnitt. Kom ihåg att, till skillnad från i C#, ger en misslyckad cast av en operatör asett undantag.

  • Referensoperatorer ^ @ - används för att arbeta med pekare.

Operatören ^refererar bort pekaren. Operatören @gör det motsatta och returnerar variabelns adress. Enkla additions- och subtraktionsoperationer stöds på maskinskrivna pekare, med tanke på storleken på de typer de pekar på ( smart pekararitmetik).

  • Uppdragsoperatör :=. I Delphi bildar inte tilldelningsoperatorn ett uttryck, utan en operation, så att "stränga" tilldelningar är inte tillåtna.

Klasser

I Object Pascal är klasser speciella datatyper som används för att beskriva objekt. Följaktligen är ett objekt som har typen av en klass en instans av denna klass eller en variabel av denna typ.

En klass är en speciell typ som har element som fält, egenskaper och metoder. Klassfält liknar postfält och används för att lagra information om ett objekt. Metoder är procedurer och funktioner som vanligtvis används för att bearbeta fält. Egenskaper är mellanliggande mellan fält och metoder.

Objektorienterade funktioner i språket

Inkapsling

Att kombinera och dölja objektdata, samt metoder som bearbetar det, i en konkret klass från användaren kallas inkapsling.

Arv

När man skapar nya objekt kallas möjligheten att få alla egenskaper och metoder från sina förfäder för arv. Sådana föremål ärver efter att de skapats alla fält, egenskaper, händelser, metoder etc. från sina förfäder. Arv räddar ofta utvecklare från rutinarbete och gör att de snabbt kan börja utveckla något nytt. Till skillnad från C++ tillåter Delphi inte multipelt arv. I Delphi är det möjligt att lägga till metoder till en klass eller post med hjälp av den så kallade klasshjälpen eller posthjälparen (klasshjälpare eller posthjälpare), som, som inte är en ättling till klassen eller posten som ändras, kan lägga till ytterligare metoder till dem. Ett exempel är TStringHelper-hjälparposten som deklareras i System.SysUtils-modulen.

Polymorfism

Delphi implementerar den klassiska polymorfismmodellen som används i tillämpade programmeringsspråk, när basklassmetoder, såväl som referensvariabler av basklasstypen, kan manipulera instanser av underklasser baserat på kontraktet som anges i basklassen. Kontraktet i detta fall är deklarationen av abstrakta metoder i basklassen.

Exempel

Programstruktur

Varje program skrivet på Delphi-språket består av en programhuvud (program NewApplication;), ett fält av använda moduler Används (till exempel Använder Windows, Meddelanden, SysUtils, etc.), som kanske inte ingår i själva strukturen, eftersom samt beskrivningsblock och exekveringar (börja med en sammansatt operator som börjar och slutar med slutet.).

program Projekt1 ; // Header för programmet, med dess namn "Project1" använder Forms , Unit1 i 'Unit1.pas' {Form1} ; // moduler som är kopplade till projektet och som används av programmet {$R *.res} börja ansökan . Initiera ; // Initiera applikationen Application . CreateForm ( TForm1 , Form1 ) ; // Skapa formulär/ fönsterapplikation . springa ; // Starta och kör end .

Exempel #1

Visar meddelandet "Hej världen!" i Delphi-konsolapplikationen

programmet Helloworld ; //programnamn {$APPTYPE CONSOLE} //direktiv till kompilatorn för att skapa en konsolapplikation start writeln ( 'Hej världen!' ) ; //utgångsmeddelande Hej världen! readln ; //vänta på att användaren trycker på en tangent slut . // slutet av programmet

Exempel #2

Visar meddelandet "Hej världen!" i en 32-bitars Delphi GUI-applikation

... procedur TForm1 . Button1Click ( Avsändare : TObject ) ; //OnClick-händelsehanteraren som genereras automatiskt börjar ShowMessage ( 'Hej världen!' ) ; //utgångsmeddelande Hej världen! slut ; //slut på proceduren ...

Exempel #3

Skapa dynamiskt en lista med strängar och skriv den till en fil.

// Hanterare för händelsen som inträffar när formuläret skapas MainForm- proceduren TMainForm . FormCreate ( Avsändare : TObject ) ; var // Deklarera en variabel av typen TStrings (lista med strängar). Strings : TStrings ; begin // Skapande (allokering av minne och fyllning av det med initiala värden) av ett objekt av typen TStringList. // TStringList är en ättling till TStrings som implementerar sina abstrakta metoder för att lagra strängar i minnet. Strings := TStringList . skapa ; försök // Lägga till en sträng. Strängar . Add ( 'Rad som ska läggas till.' ) ; // Spara alla rader i en fil. Strängar . SaveToFile ( 'C:\Strings.txt' ) ; slutligen // Avallokera objektets minne och rensa dess referens för att förhindra oavsiktlig åtkomst till icke-allokerat minne. FreeAndNil ( strängar ) ; slut ; slut ;

Filtillägg

  • .pas - modulkällkod (pascal)
  • .dpr - projektkällkod (pascal)
  • .dproj — projektkällkod (xml)
  • .dproj.local — projektkällkod (xml)
  • .dfm - formuläret källkod
  • .dpk - paketprojektets källkod
  • .bpl - kompilerat paket
  • .dcu - kompilerad modul
  • .exe - sammanställd applikation
  • .res - Resurser
  • .dsk - fillänkar
  • .identcache - cachade filassociationer

Anmärkningsvärd Delphi-programvara

Bland de många vanliga mjukvaruprodukterna skrivna i Delphi kan man hitta [13] :

Kritik

Kritik av språket i de tidiga utvecklingsstadierna

Historien om kritiken av Pascal går tillbaka till 1981 och Brian Kernighans arbete [15] , vars argument för det mesta har blivit föråldrade i takt med att språket har utvecklats.

Innovationer för sammanställning på mobila plattformar

Vissa språkändringar implementerade av Embarcadero (språkutvecklare) i de så kallade Delphi NextGen-kompilatorerna bröt avsiktligt kompatibiliteten med den ackumulerade källkodsbasen. Dessa förändringar mottogs negativt av ett brett spektrum av erfarna Delphi-utvecklare, eftersom, även om de förde språket närmare .NET-språkparadigmet, bröt de traditionen med hög bakåtkompatibilitet och gjorde det mycket svårare att portera befintlig källkod till programvara för mobila plattformar. Följande förändringar utmanade själva paradigmet med multiplattformsutveckling med en enda källa som främjas av Embarcadero.

  • införande av nollbasindexering av strängar

Sedan Pascal har den inbyggda strängtypen historiskt indexerats med basen ett: "null"-elementet i strängen returnerade längden på strängen. När nya (”långa” och “unicode”) strängtyper introducerades, bibehölls denna indexeringsordning, vilket gav en nästan sömlös portabilitet av kodbasen till uppdaterade versioner av språket. Men med introduktionen av nästagen kompilering förändrades paradigmet: i nya kompilatorer började strängar indexeras med nollbas, som i familjen C-liknande språk (C ++, C #, Java), medan i de "klassiska" kompilatorerna för Windows och Mac OS har paradigmet med enkel indexering sparats.

  • införande av en icke-alternativ referensräkningsmekanism för klassinstanser

Historiskt sett är klasser och deras instanser implicita referensstrukturtyper. Livstidshanteringen av en klassinstans gjordes dock ursprungligen manuellt - genom att uttryckligen anropa konstruktorn och destruktorn (eller metoden Free()), och denna funktion är bevarad (från 2018) i de klassiska versionerna av kompilatorer. Referensräkning fungerade endast för klasser som implementerar gränssnitt, och dessutom endast i de fall då sådana klasser manipulerades genom variabler av gränssnittstypen.

Före version 10.4 introducerade kompilatorer för mobila plattformar referensräkning för alla instanser av klasser, vilket i grunden förändrade paradigmet för objektlivstidshantering, eftersom "manuell" hantering praktiskt taget (förutom vissa mycket avancerade tekniker) är inkompatibel med det nya paradigmet.

Sedan version 10.4 har en enhetlig minneshanteringsmekanism [16] introducerats , när den klassiska implementeringen av objektminneshantering används för mobil, stationär och server. ARC-minneshanteringsmodellen fanns kvar för att hantera strängar och referenser för gränssnittstyp på alla plattformar.

Långsam utveckling av språk betyder

Många utvecklare ser Delphis konservatism som en dygd som gör koden mycket portabel och även gör språket lättare för nybörjare att förstå.

Men för närvarande är situationen sådan att ny teknik, paradigm och till och med programmeringsspråk dyker upp (och vinner popularitet) nästan varje år. Utvecklingen av språkverktyg innebär inte alltid att bakåtkompatibilitet förkastas.

Ett utmärkt exempel på detta tillvägagångssätt är

en sen introduktion till språket för att deklarera lokala variabler i ett block

Före kompilatorversion 33.0 (Delphi 10.3 Rio) måste deklarationen av en lokal variabel föregå den första instruktionen av funktionskoden, och initiering av lokala (stack)variabler på deklarationsplatsen är inte tillåten. Typinferens var också omöjlig.

Som jämförelse, att deklarera en lokal variabel var som helst i en funktion stöddes naturligt i C, och ärvdes av nästan alla språk som höll sig till den C-liknande stilen - C++, C#, Java, etc.

Införandet av denna språkfunktion i Delphi diskuterades länge, men på den tiden mötte det inte språkutvecklarnas förståelse.

Samtidigt kan deklarering av lokala variabler inuti ett block, förutom For loop-operationerna, leda till att läsbarheten av koden för stora projekt kompliceras.

Anteckningar

  1. ↑ Tillgänglighetsmeddelande för RAD Studio 11.1 Alexandria . Arkiverad från originalet den 20 april 2022. Hämtad 12 april 2022.
  2. "del-phi" uttal dominerar i Storbritannien: en variant av uttal som är karakteristiskt för Storbritannien  (engelska)  (otillgänglig länk) . Merriam-Webster Online Dictionary . Merriam Webster. Hämtad 1 oktober 2008. Arkiverad från originalet 21 augusti 2011. , och i USA  - "del-fi": en variant av uttalet som är typiskt för USA  (engelska)  (otillgänglig länk) . Merriam-Webster Online Dictionary . Merriam Webster. Hämtad 1 oktober 2008. Arkiverad från originalet 21 augusti 2011.
  3. David T. Craig. Apple Lisa Computer: Apples och Pascals historia .
  4. Delphi Language Overview  (nedlänk)
  5. körs direkt på ARM-processorn )
  6. Dmitry Ivanov - Berättelser om för tidig optimeringYouTube , med start 35:40
  7. Roman Elizarov - Miljontals citat per sekund i ren JavaYouTube , med start 58:59
  8. Detta indikeras av kompilatorns versionsbeteckningar. Så i Delphi 7 har kompilatorn versionsnumret 15.0 (den senaste versionen av Borland Pascal / Turbo Pascal benämndes 7.0, i Delphi 1 har kompilatorn version 8.0, i Delphi 2 - 9.0, etc. Versionsnumret 11.0 är Pascal-kompilatorn, som var en del av miljön C++ Builder ).
  9. Standard Parallels Plesk Panel-sida Arkiverad 5 december 2006.
  10. Delphi och C++Builder Roadmap (nedlänk) . Hämtad 18 juli 2007. Arkiverad från originalet 10 oktober 2007. 
  11. Databasverktyg och utvecklarprogramvara | Embarcadero Technologies (inte tillgänglig länk) . Tillträdesdatum: 25 augusti 2008. Arkiverad från originalet 29 augusti 2008. 
  12. Delphi från Embarcadero | Arkiverad från originalet den 10 juli 2008. RAD Application Development Software
  13. Applikationer av god kvalitet byggda med Delphi - Delphi-programmering arkiverad 30 juni 2011 på Wayback Machine 
  14. MAXIMA elektroniskt kösystem . mtg-biz.ru. Tillträdesdatum: 5 januari 2017. Arkiverad från originalet 6 januari 2017.
  15. Varför Pascal inte är mitt favoritprogrammeringsspråk . Tillträdesdatum: 23 maj 2016. Arkiverad från originalet 28 april 2009.
  16. Vad är nytt i RAD Studio 10.4 Sydney - RAD Studio - Produkter .features-tabs ul.nav.nav-tabs Vad är nytt i RAD Studio 10.4 RAD Studio 10.4 ger avsevärt förbättrat, högpresterande inbyggt Windows-stöd, ökad produktivitet med  flammande )  ? . Embarcadero webbplats . Hämtad 15 september 2020. Arkiverad från originalet 16 september 2020.

Litteratur

Länkar