Si të konfiguroni telefonat inteligjentë dhe PC. Portali informativ

Gjuha e programimit Rust. Pasqyrë e gjuhës programuese Rust

Në vitin 2013, Mozilla, së bashku me Samsung, njoftuan zhvillimin e një motori të ri të shfletuesit të internetit, Servo. Ai u krijua posaçërisht për procesorë me shumë bërthama të pajisjeve celulare, është i aftë të ndajë detyrat në fije paralele dhe të zvogëlojë shumë kohën e ngarkimit të faqeve në internet. Servo është shkruar tërësisht në gjuhën e programimit Rust, të cilën Mozilla e ka zhvilluar vetë për të shkruar aplikacione celulare.

Rreth gjuhës

Rust është një gjuhë programimi procedurale që mbështet një sërë stilesh kodimi. Zhvilluesi Graydon Hoare filloi krijimin e gjuhës në vitin 2006 dhe tre vjet më vonë Mozilla iu bashkua projektit. Në vitin 2010, Rust u prezantua në konferencën e Samitit të Mozilla-s. Në të njëjtin vit, zhvillimi u transferua në një përpilues të shkruar në Rust. Përpiluesi përdori sistemin universal të analizës dhe transformimit të programit LLVM si bazë të dhënash.

Versioni i parë i qëndrueshëm i gjuhës u lëshua në 2015. Pas lëshimit të versionit alfa, Rust pësoi ndryshime - brenda përpiluesit mbetën vetëm veçori të gatshme që nuk do të ndryshojnë. Gjithçka tjetër u zhvendos në seksionin eksperimental.

Në zemër të gjuhës, Graydon Hoare parashtroi koncepte të tilla si:

  • Siguria. Rust përmban një numër kufizimesh të programuesit që janë aktivizuar si parazgjedhje. Për t'i çaktivizuar ato, kërkohet etiketa "i pasigurt" në blloqe dhe funksione.
  • Shpejtësia. Gjuha është e krahasueshme në shpejtësi me një gjuhë tjetër programimi, C++, e cila ofron një numër të qartë avantazhesh për programuesin.
  • Paralelizmi. Sistemi mund të kryejë disa llogaritje në të njëjtën kohë, dhe në të njëjtën kohë ato mund të ndërveprojnë me njëri-tjetrin.
  • Shkurtësi. Fjalët kyçe të para në Rust ishin të kufizuara në pesë karaktere. Por më vonë ky kufizim u hoq.

Një shembull i një prej kodeve të para në Rust

Sidoqoftë, Rust nuk është pa të metat e tij, më të habitshmet prej të cilave janë:

  • Teprica e kodit.
  • Mungesa e literaturës për mësimin e gjuhës.
  • Qartësia në futjen e parametrave të kompilimit. Kjo nuk u përshtatet gjithmonë programuesve me përvojë, pasi gjuhët e tjera nuk kanë rregulla të ngjashme.

Sidoqoftë, gjuha modernizohet dhe zgjerohet rregullisht: përditësimet e saj lëshohen çdo 6 javë.

Krahasimi i Rust me C++

Krijuesit e Rust e konsiderojnë atë pasardhësin e C++, i cili u shfaq në fillim të viteve 1980, kur zhvilluesi doli me disa përmirësime në gjuhën C. Prandaj, ia vlen të krahasohet gjuha e re dhe ende në ndryshim me atë të testuar me kohë.

  • Duke hyrë në kujtesën në distancë. Në C++, fshirja e një ndryshoreje mund të shkaktojë një sërë problemesh. Komplikime të tilla nuk janë të mundshme në Rust, pasi nuk ka komanda për fshirjen e kujtesës. Kompiluesi pasardhës do të raportojë se kodi që keni shkruar përmban një gabim dhe përpiluesi C++ do të nxjerrë rezultatin pa vlerat e hequra, madje pa raportuar problemin.
  • Pikëpresje. Shtimi i një pikëpresjeje shtesë në kodin tuaj do të shkaktojë një gabim në C++, ndërsa në Rust trupi i lakut është i mbyllur në kllapa kaçurrelë.
  • Kodi i pasigurt. Rust ka një etiketë "të pasigurt" që izolon kodin kryesor nga kodi i pasigurt. Në të ardhmen, kur rishikoni kodin, kjo ju lejon të kufizoni kërkimin për dobësitë.

Firefox-i u implementua në C++: kjo gjuhë kapriçioze kërkonte më shumë vëmendje ndaj detajeve. Përndryshe, gabimet u kthyen në dobësi serioze. Rust u krijua për të zgjidhur këtë problem.

Perspektivat

Në renditjen RedMonk për tremujorin e tretë të 2018, gjuha e programimit Mozilla renditet vazhdimisht në vendin e 23-të. Ekspertët besojnë se pozita e tij nuk rrezikon të përmirësohet. Përkundër kësaj, në gusht 2018 krijuesit lëshuan Rust 1.28 të përditësuar.

Pas publikimit të Rust në 2015, sipas Stack Overflow, 74% e zhvilluesve donin të njiheshin me të. Sidoqoftë, tashmë në vitin 2016, ajo u zhvendos në vendin e parë: 79% e përdoruesve emëruan Rust si gjuhën e tyre të preferuar të programimit dhe shprehën dëshirën për të vazhduar punën me të. Rust zuri vendin e parë në këtë parametër në 2018.

Stack Overflow është një sistem i njohur programimi i pyetjeve dhe përgjigjeve i zhvilluar në 2008.

Popullariteti i Rust konfirmohet nga numri i kompanive që e përdorin atë në zhvillimin e tyre. Aktualisht, kjo listë përfshin 105 organizata.

Pra, dëshirojmë të prezantojmë në vëmendjen tuaj një djalë të ditëlindjes së fundit (ai mbushi një vjeç më 15 maj 2016) - Rust. Kjo është një gjuhë programimi universale e zhvilluar nga Mozilla, tre parimet kryesore të së cilës janë: shpejtësia, siguria dhe ergonomia. Vetë krijuesit e konsiderojnë atë në mënyrë jo modeste si një nga pasardhësit më të mundshëm të C/C++. Sipas një sondazhi në portalin StackOverflow, Rust është gjuha më e preferuar në mesin e zhvilluesve sot. Pra, le të hedhim një vështrim më të afërt se çfarë është.

Ndryshk për një fillestar

Nuk dua të mashtroj askënd, kështu që ja një deklaratë e përgjegjshme: Ndryshku është mjaft i vështirë për t'u mësuar. Së pari, kjo është për shkak të rinisë së gjuhës dhe, si rrjedhojë, sasisë së vogël të letërsisë. Së dyti, mund të jetë edhe më e lehtë për një person larg programimit që ta mësojë atë sesa për dikë që njihet me gjuhë të tjera. Kështu, për shembull, një specialist i gatshëm i IT-së do të mërzitet shumë nga nevoja për të përshkruar operacionet më të vogla, dhe mungesa e trashëgimisë si e tillë në gjuhë thjesht do ta ngatërrojë atë.

Sidoqoftë, Rust po zhvillohet me shpejtësi (një version i ri lëshohet çdo 6 javë), komuniteti po rritet dhe gjetja e informacionit në internet nuk është më e vështirë.

Si të studiojmë

Ju mund të gjeni pothuajse gjithçka që ju nevojitet në faqen zyrtare të internetit. Për më tepër, komuniteti i ndjekësve të Rust është shumë i madh dhe miqësor, kështu që gjithmonë mund t'i drejtoheni IRC (ekziston një seksion rus) dhe forumi zyrtar për këshilla. Përveç kësaj, librat, përfshirë ato elektronike, filluan të shfaqen pak nga pak. Është ende e vështirë të vlerësohet cilësia e tyre, por ky është një fakt.

Për ata që kanë kaluar fazën fillestare të njohjes, mund të gjeni shumë materiale të dobishme në GiHub, duke përfshirë RFC-të dhe angazhimet. Përveç kësaj, ju mund të merrni pjesë personalisht ose të paktën të shikoni transmetimin në internet të një prej konferencave Rust të planifikuara për gjysmën e dytë të vitit. Këtu është kalendari:

  • 9-10 shtator Konferenca RustConf në Portland, SHBA;
  • 17 shtator, Konferenca e Komuniteteve Evropiane RustFest në Berlin, Gjermani;
  • 27 tetor Konferenca Rust Belt Rust në Pittsburgh, SHBA;

Epo, për të takuar ata që e konsiderojnë Rust thirrjen e tyre, dhe në të njëjtën kohë t'u kërkoni atyre gjithë mençurinë e tyre, mund të kontaktoni organizatorët dhe pjesëmarrësit e takimeve të tifozëve të gjuhës në Moskë.

Veçoritë

Duke kopjuar pak atë që u tha më herët, ne do të nxjerrim në pah të mirat dhe të këqijat kryesore të gjuhës Rust.

Të mirat:

  • Punë e sigurt me memorie;
  • Performancë e lartë;
  • Lloji i të dhënave algjebrike;
  • Parashikueshmëria e përpilimit;

Minuset:

  • Disa teprica të kodit;
  • Intensiteti i lartë i zhvillimit gjuhësor dhe, si pasojë, mungesa e literaturës së mirë përkatëse për studim;
  • Nevoja për të specifikuar qartë dhe pa mëdyshje parametrat për përpilim.

Në fakt, ju mësoheni shpejt me dallimet, të tilla si zëvendësimi i trashëgimisë me aftësi. Sapo të mësohen sytë dhe duart mësohen me të, Rust kthehet në një gjuhë plotësisht funksionale, më e thjeshtë dhe më funksionale se C++, por inferiore në “bukuri” ndaj shumë gjuhëve të tjera programimi. Në fakt, ndryshimi kryesor midis Rust dhe konkurrentëve dhe paraardhësve të tij është shpejtësia dhe siguria.

Kërkesa

Sot, Rust është i popullarizuar në mesin e zhvilluesve të lojërave, grafikëve dhe sistemeve operative. Sidoqoftë, për arsye të dukshme, numri i vendeve të palëvizshme ku kërkohen ekspertë shumë të specializuar të Rust është jashtëzakonisht i vogël në botë, dhe aq më tepër në Rusi. Megjithatë, nuk ka ende shenja se gjuha do të zhytet në harresë, ajo duket më shumë si një pushtim sistematik i botës. Kjo do të thotë se aftësitë e mira në përdorimin e Rust në të ardhmen do t'ju ndihmojnë të gjeni një punë të paguar mirë, interesante si në vendin tonë ashtu edhe jashtë saj.

Ende në kërkesë: profesioni "".

Ndryshkështë një gjuhë e re programimi eksperimentale që po zhvillohet nga Mozilla. Gjuha është e përpiluar dhe multi-paradigmë, e pozicionuar si një alternativë ndaj C/C++, e cila në vetvete është interesante, pasi nuk ka edhe aq shumë pretendentë për konkurrencë. Ju mund të mbani mend Walter Bright's D ose Google's Go.
Rust mbështet programimin funksional, paralel, procedural dhe të orientuar nga objekti, d.m.th. pothuajse të gjithë gamën e paradigmave të përdorura në të vërtetë në programimin e aplikacioneve.

Synimi im nuk është të përkthej dokumentacionin (përveç kësaj, ai është shumë i pakët dhe po ndryshon vazhdimisht, pasi ende nuk ka një lëshim zyrtar të gjuhës), përkundrazi dua të nxjerr në pah veçoritë më interesante të gjuhës. Informacioni u mblodh si nga dokumentacioni zyrtar, ashtu edhe nga përmendjet jashtëzakonisht të pakta të gjuhës në internet.

Përshtypja e parë

Sintaksa e gjuhës është ndërtuar në një stil tradicional të ngjashëm me C-në (që është një lajm i mirë, pasi ky është tashmë një standard de facto). Natyrisht, janë marrë parasysh gabimet e njohura të dizajnit C/C++.
Një Hello World tradicionale duket kështu:
përdorni std; fn main(args: ) ( std::io::println ("përshëndetje botë nga " + args + "!");

Një shembull pak më i komplikuar - funksioni i llogaritjes faktoriale:

Fn fac(n: int) -> int ( le të rezultojë = 1, i = 1; ndërsa i<= n { result *= i; i += 1; } ret result; }

Siç mund ta shihni nga shembulli, funksionet deklarohen në stilin "funksional" (ky stil ka disa përparësi ndaj "int fac(int n)" tradicionale). Ne shohim konkluzioni automatik i tipit(le fjalë kyçe), nuk ka kllapa në argumentin while (njëlloj si Go). Një tjetër gjë që ju bie menjëherë në sy është kompaktësia e fjalëve kyçe. Krijuesit e Rust me të vërtetë menduan t'i mbanin të gjitha fjalët kyçe sa më të shkurtra të jetë e mundur, dhe të jem i sinqertë, më pëlqen.

Karakteristika sintaksore të vogla por interesante

  • Ju mund të futni nënvizat në konstante numerike. Ky është një veçori e dobishme, kjo veçori tani po shtohet në shumë gjuhë të reja.
    0xffff_ffff_ffff_ffff_ffff_ffff
  • Konstante binare. Sigurisht, një programues i vërtetë duhet ta shndërrojë koshin në heks në kokën e tij, por është më i përshtatshëm në këtë mënyrë! 0b1111_1111_1001_0000
  • Trupat e çdo deklarate (madje edhe ato që përbëhen nga një shprehje e vetme) duhet të mbyllen në kllapa kaçurrelë. Për shembull, në C mund të shkruani if(x>0) foo(); , në Rust duhet të vendosni mbajtëse kaçurrelë rreth foo()
  • Por argumentet e if, while dhe operatorëve të ngjashëm nuk kanë nevojë të futen në kllapa
  • në shumë raste, blloqet e kodit mund të mendohen si shprehje. Në veçanti, sa vijon është e mundur:
    le të x = nëse the_stars_align() ( 4 ) other if something_else () ( 3 ) other ( 0 );
  • sintaksa e deklarimit të funksionit - fillimisht fjala kyçe fn, pastaj një listë argumentesh, lloji i argumentit tregohet pas emrit, pastaj, nëse funksioni kthen një vlerë, një shigjetë "->" dhe llojin e vlerës së kthyer
  • Variablat deklarohen në të njëjtën mënyrë: fjala kyçe let, emri i ndryshores, pas variablit mund të specifikoni llojin përmes dy pikave dhe më pas të caktoni një vlerë fillestare.
    le të numërojmë: int = 5;
  • si parazgjedhje, të gjitha variablat janë të pandryshueshme; Fjala kyçe e ndryshueshme përdoret për të deklaruar variabla të ndryshueshme.
  • emrat e llojeve bazë janë më kompaktet nga të gjitha që kam hasur: i8, i16, i32, i64, u8, u16, u32, u64, f32, f64
  • siç u përmend më lart, konkluzioni automatik i tipit mbështetet
Gjuha ka mjete të integruara për korrigjimin e programit:
Fjalë kyçe dështojnë përfundon procesin aktual
Fjalë kyçe log nxjerr çdo shprehje gjuhësore në regjistër (për shembull, në stderr)
Fjalë kyçe pohoj kontrollon shprehjen dhe nëse është false, përfundon procesin aktual
Fjalë kyçe shënim ju lejon të shfaqni informacion shtesë në rast të përfundimit jonormal të procesit.

Llojet e të dhënave

Rust, si Go, mbështet tipizimi strukturor(megjithëse, sipas autorëve, gjuhët u zhvilluan në mënyrë të pavarur, kështu që ky është ndikimi i paraardhësve të tyre të zakonshëm - Alef, Limbo, etj.). Çfarë është shtypja strukturore? Për shembull, ju keni një strukturë të deklaruar në një skedar (ose, në terminologjinë Rust, një "rekord")
tip pikë = (x: float, y: float);
Ju mund të deklaroni një grup variablash dhe funksionesh me lloje të argumentit "pikë". Pastaj, diku tjetër, mund të deklaroni një strukturë tjetër, si p.sh
shkruani MySuperPoint = (x: float, y: float);
dhe variablat e këtij lloji do të jenë plotësisht në përputhje me variablat e tipit pikë.

Në të kundërt, shtypja nominative e miratuar në C, C++, C# dhe Java nuk lejon konstruksione të tilla. Me shtypjen nominative, çdo strukturë është një lloj unik, i papajtueshëm si parazgjedhje me llojet e tjera.

Strukturat në Rust quhen "rekorde". Ka edhe tuples - këto janë të njëjtat regjistrime, por me fusha pa emër. Elementet e një tuple, ndryshe nga elementët e një regjistrimi, nuk mund të jenë të ndryshueshëm.

Ka vektorë - në disa mënyra të ngjashme me vargjet e zakonshme, dhe në disa mënyra të ngjashme me llojin std::vector nga stl. Kur inicializohet me një listë, përdoren kllapa katrore, jo kllapa kaçurrela si në C/C++

Le të myvec = ;

Një vektor, megjithatë, është një strukturë dinamike e të dhënave, në veçanti, vektorët mbështesin lidhjen.

Le të v: i ndryshueshëm = ; v += ;

Ka shabllone. Sintaksa e tyre është mjaft logjike, pa rrëmujë të "shabllonit" nga C++. Modelet e funksioneve dhe të tipit të të dhënave mbështeten.

Fn për_rev (v: [T], akt: bllok(T)) ( le të i = std::vec::len (v); ndërsa i > 0u ( i -= 1u; akt(v[i]); ) ) lloji rrethore_buf = (fillimi: uint, fundi: uint, buf: );

Gjuha mbështet të ashtuquajturat etiketat. Ky nuk është asgjë më shumë se një bashkim nga C, me një fushë shtesë - kodi i opsionit të përdorur (d.m.th., diçka e përbashkët midis një bashkimi dhe një numërimi). Ose, nga pikëpamja teorike, një lloj të dhënash algjebrike.

Forma e etiketës (rrethi (pika, noti); drejtkëndësh (pika, pika); )

Në rastin më të thjeshtë, një etiketë është identike me një numërim:

Tag kafshë ( qen; mace; ) le një: kafshë = qen; a = mace;
Në raste më komplekse, çdo element i "numërimi" është një strukturë e pavarur që ka "konstruktorin" e vet.
Një shembull tjetër interesant është një strukturë rekursive që përdoret për të përcaktuar një objekt të llojit "listë":
lista e etiketave ( zero; kundër (T, @list ); ) le një: listë = kundër (10, @cons (12, @nil));
Etiketat mund të marrin pjesë në shprehjet e përputhjes së modeleve, të cilat mund të jenë mjaft komplekse.
alt x (cons(a, @cons(b, _)) (proces_pair (a,b); ) cons(10, _) (proces_dhjetë (); ) _ (dështon; ) )

Përputhja e modelit

Për të filluar, ne mund ta konsiderojmë modelin e përputhjes si një ndërprerës të përmirësuar. Përdoret fjala kyçe alt, e ndjekur nga shprehja që analizohet, dhe më pas në trupin e deklaratës - modelet dhe veprimet nëse modelet përputhen.
alt my_number ( 0 ( std::io::println ("zero"); ) 1 | 2 ( std::io::println ("një ose dy"); ) 3 deri në 10 ( std::io::println ("tre deri në dhjetë") _ (std::io::println("diçka tjetër"); )
Si "modele" mund të përdorni jo vetëm konstante (si në C), por edhe shprehje më komplekse - variabla, tuples, vargje, lloje, mbajtëse vendesh ("_"). Ju mund të specifikoni kushte shtesë duke përdorur deklaratën kur menjëherë pas modelit. Ekziston një variant i veçantë i operatorit për përputhjen e tipit. Kjo është e mundur sepse gjuha ka një tip variant universal ndonjë, objektet e të cilit mund të përmbajnë vlera të çdo lloji.

Treguesit. Përveç treguesve të zakonshëm "C", Rust mbështet tregues të veçantë "të zgjuar" me numërim të integruar të referencës - të përbashkët (kutitë e përbashkëta) dhe unike (kutitë unike). Ato janë disi të ngjashme me shared_ptr dhe unique_ptr nga C++. Ata kanë sintaksën e tyre: @ për të përbashkët dhe ~ për unike. Për treguesit unikë, në vend të kopjimit, ekziston një operacion i veçantë - lëvizja:
le të x = ~ 10; le y<- x;
Pas një lëvizje të tillë, treguesi x deinitializohet.

Mbyllje, aplikime të pjesshme, përsëritës

Këtu fillon programimi funksional. Rust mbështet plotësisht konceptin e funksioneve të rendit më të lartë - domethënë funksionet që mund të marrin funksione të tjera si argumente dhe t'i kthejnë ato.

1. Fjalë kyçe lambda përdoret për të deklaruar një funksion të ndërlidhur ose një lloj të dhënash funksionale.

Fn make_plus_function(x: int) -> lambda(int) -> int (lambda(y: int) -> int (x + y) ) le plus_dy = make_plus_function(2); pohoj plus_dy (3) == 5;

Në këtë shembull, ne kemi një funksion make_plus_function që merr një argument "x" të tipit int dhe kthen një funksion të tipit "int->int" (lambda është fjala kyçe këtu). Trupi i funksionit përshkruan pikërisht këtë funksion. Mungesa e një operatori "kthimi" është pak konfuze, por kjo është një gjë e zakonshme për FP-të.

2. Fjalë kyçe bllokoj përdoret për të deklaruar një tip funksional - një argument funksioni, i cili mund të zëvendësohet me diçka të ngjashme me një bllok kodi të rregullt.
fn harta_int(f: bllok(int) -> int, vec: ) -> (le rezultat = ; për i në vec (rezultat += ;) ret rezultat; ) map_int((|x| x + 1 ), );

Këtu kemi një funksion, hyrja e të cilit është një bllok - në thelb një funksion lambda i tipit "int->int", dhe një vektor të tipit int (më shumë për sintaksën e vektorëve më vonë). Vetë "blloku" është shkruar në kodin thirrës duke përdorur një sintaksë disi të pazakontë (|x| x + 1). Personalisht, unë preferoj lambdas në C#, simboli | perceptohet vazhdimisht si OR bitwise (i cili, nga rruga, është gjithashtu i pranishëm në Rust, si të gjitha operacionet e vjetra të bazuara në C).

3. Zbatimi i pjesshëm është krijimi i një funksioni të bazuar në një funksion tjetër me më shumë argumente duke specifikuar vlerat e disa prej argumenteve të atij funksioni tjetër. Fjala kyçe e përdorur për këtë është lidh dhe një karakter mbajtës vendi "_":

Le të daynum = lidh std::vec::position(_, ["mo", "tu", "ne", "do", "fr", "sa", "su"])

Për ta bërë më të qartë, do të them menjëherë se kjo mund të bëhet në C të rregullt duke krijuar një mbështjellës të thjeshtë, diçka si kjo:
const char* daynum (int i) (const char *s =("mo", "tu", "ne", "do", "fr", "sa", "su"); kthej s[i]; )

Por aplikimi i pjesshëm është një stil funksional, jo procedural (nga rruga, nga shembulli i dhënë nuk është e qartë se si të bëhet një aplikim i pjesshëm për të marrë një funksion pa argumente)

Një shembull tjetër: funksioni add deklarohet me dy argumente int, duke kthyer int. Më pas, deklarohet tipi funksional single_param_fn, i cili ka një argument int dhe kthen int. Duke përdorur bind, deklarohen dy objekte të funksionit add4 dhe add5, të ndërtuara në bazë të funksionit add, i cili ka argumente të specifikuara pjesërisht.

Fn add(x: int, y: int) -> int (ret x + y; ) tip single_param_fn = fn(int) -> int; le të shtoj4: single_param_fn = lidh add(4, _); le të shtoni5: single_param_fn = lidhë shtoni(_, 5);

Objektet e funksionit mund të thirren në të njëjtën mënyrë si funksionet e rregullta.
pohoj (shtoj(4,5) == shtoj4(5)); pohoj (shtoj(4,5) == shtoj5(4));

4. Funksionet dhe kallëzuesit e pastër
Funksionet e pastra janë funksione që nuk kanë efekte anësore (përfshirë ato që nuk thërrasin asnjë funksion tjetër përveç atyre të pastra). Funksione të tilla identifikohen me fjalën kyçe të pastër.
i pastër fn lt_42(x: int) -> bool (ret (x< 42); }
Kallëzuesit janë funksione të pastra që kthejnë tipin bool. Funksione të tilla mund të përdoren në sistemin tipstate (shih më poshtë), domethënë thirren në fazën e përpilimit për kontrolle të ndryshme statike.

Makrot sintaksore
Një veçori e planifikuar, por shumë e dobishme. Është ende në zhvillim të hershëm në Rust.
std::io::println(#fmt("%s është %d", "përgjigja", 42));
Një shprehje e ngjashme me printf-in e C-së, por e ekzekutuar në kohën e kompilimit (përkatësisht, të gjitha gabimet e argumentit zbulohen në fazën e përpilimit). Fatkeqësisht, ka shumë pak materiale për makrot sintaksore, dhe ato vetë janë në zhvillim e sipër, por ka shpresë se diçka si makrot Nemerle do të dalë.
Meqë ra fjala, ndryshe nga i njëjti Nemerle, unë e konsideroj vendimin për të theksuar makrot në mënyrë sintaksore duke përdorur simbolin # të jetë shumë i zgjuar: një makro është një ent që është shumë i ndryshëm nga një funksion dhe mendoj se është e rëndësishme të shihet në shikimi i parë ku në kod thirren funksionet dhe ku - makro.

Atributet

Një koncept i ngjashëm me atributet C# (dhe madje me sintaksë të ngjashme). Falënderime të veçanta për zhvilluesit për këtë. Siç do të prisnit, atributet shtojnë meta informacion në entitetin që shënojnë.
# fn register_win_service() ( /* ... */ )
Një tjetër variant i sintaksës së atributeve është shpikur - e njëjta rresht, por me një pikëpresje në fund, tregon kontekstin aktual. Kjo është, ajo që përputhet me mbajtëset më të afërta kaçurrelë që mbyllin një atribut të tillë.
fn register_win_service() (#; /* ... */)

Llogaritja paralele

Ndoshta një nga pjesët më interesante të gjuhës. Në të njëjtën kohë, nuk përshkruhet fare në tutorial për momentin :)
Një program Rust përbëhet nga një "pemë detyrash". Çdo detyrë ka një funksion të hyrjes, stivën e vet, mjetet e ndërveprimit me detyrat e tjera - kanalet për informacionin dalës dhe portat për informacionin hyrës, dhe zotëron disa nga objektet në grumbullin dinamik.
Detyra të shumta Rust mund të ekzistojnë brenda një procesi të vetëm të sistemit operativ. Detyrat e ndryshkut janë "të lehta": secila detyrë konsumon më pak memorie sesa procesi OS, dhe kalimi midis tyre është më i shpejtë se kalimi midis proceseve të OS (këtu, me siguri, nënkuptojmë "fije").

Një detyrë përbëhet nga të paktën një funksion pa argumente. Detyra niset duke përdorur funksionin e pjelljes. Çdo detyrë mund të ketë kanale përmes të cilave transmeton informacion në detyra të tjera. Një kanal është një kanal i veçantë i tipit shabllon, i parametrizuar nga lloji i të dhënave të kanalit. Për shembull, chan është një kanal për transmetimin e bajteve të panënshkruara.
Për të dërguar në një kanal, përdorni funksionin dërgoni, argumenti i parë i të cilit është kanali dhe i dyti është vlera që do të dërgohet. Ky funksion në fakt e vendos vlerën në buferin e brendshëm të kanalit.
Portat përdoren për të marrë të dhëna. Një port është një lloj porti gjenerik, i parametrizuar nga një lloj i të dhënave porti: porti është një port për marrjen e bajteve të panënshkruara.
Për të lexuar nga portet, përdorni funksionin recv, argumenti i të cilit është porti dhe vlera e kthyer është të dhënat nga porti. Leximi bllokon detyrën, d.m.th. nëse porti është bosh, detyra hyn në gjendjen e pritjes derisa një detyrë tjetër të dërgojë të dhëna në kanalin e lidhur me portin.
Lidhja e kanaleve me portet është shumë e thjeshtë - duke inicializuar kanalin me një port duke përdorur fjalën kyçe chan:
le reqport = port();
le reqchan = chan(reqport);
Disa kanale mund të lidhen me një port, por jo anasjelltas - një kanal nuk mund të lidhet me disa porte në të njëjtën kohë.

Lloji i gjendjes

Unë nuk kam gjetur një përkthim të pranuar përgjithësisht në rusisht të konceptit "typestate", kështu që unë do ta quaj atë "shtetjet e tipit". Thelbi i kësaj veçorie është se përveç kontrollit të zakonshëm të tipit të miratuar në shtypjen statike, kontrolle shtesë kontekstuale janë të mundshme në fazën e përpilimit.
Në një formë ose në një tjetër, gjendjet e tipit janë të njohura për të gjithë programuesit - sipas mesazheve të përpiluesit, "ndryshorja përdoret pa inicializim". Përpiluesi zbulon vendet ku po lexohet një variabël që nuk është shkruar kurrë dhe lëshon një paralajmërim. Në një formë më të përgjithshme, kjo ide duket kështu: çdo objekt ka një sërë gjendjesh që mund të marrë. Çdo gjendje përcakton operacione të vlefshme dhe të pavlefshme për atë objekt. Dhe përpiluesi mund të kontrollojë nëse një operacion specifik në një objekt lejohet në një vend të caktuar në program. Është e rëndësishme që këto kontrolle të kryhen në kohën e përpilimit.

Për shembull, nëse kemi një objekt të tipit "file", atëherë ai mund të ketë një gjendje "të mbyllur" dhe "të hapur". Dhe një operacion leximi nga një skedar nuk lejohet nëse skedari është i mbyllur. Në gjuhët moderne, është e zakonshme që funksioni i leximit ose të hedhë një përjashtim ose të kthejë një kod gabimi. Një sistem i gjendjes së tipit mund të zbulojë një gabim të tillë në kohën e përpilimit - ashtu si përpiluesi përcakton që një operacion leximi në një ndryshore ndodh përpara çdo operacioni të mundshëm shkrimi, ai mund të përcaktojë se metoda "Read" është e vlefshme në gjendjen "skedar i hapur". , thirret përpara metodës “Open”, e cila e transferon objektin në këtë gjendje.

Rust ka konceptin e "kallëzuesit" - funksione të veçanta që nuk kanë efekte anësore dhe kthejnë një lloj bool. Funksione të tilla mund të përdoren nga përpiluesi për t'u thirrur në fazën e kompilimit me qëllim të kontrolleve statike të kushteve të caktuara.

Kufizimet janë kontrolle të veçanta që mund të kryhen në kohën e përpilimit. Për këtë përdoret fjala kyçe "check".
fn e pastër është_më pak_than(int a, int b) -< bool { ret a < b; } fn test() { let x: int = 10; let y: int = 20; check is_less_than(x,y); }
Kallëzuesit mund të "varen" në parametrat hyrës të funksioneve në këtë mënyrë:
testi fn(int x, int y) : është_më pak_se(x,y) ( ... )

Ka shumë pak informacion mbi tiparet, kështu që shumë aspekte janë ende të paqarta, por koncepti është gjithsesi interesant.

Kjo eshte e gjitha. Është shumë e mundur që ende kam humbur disa pika interesante, por artikulli ishte tashmë i fryrë. Nëse dëshironi, tani mund të ndërtoni një përpilues Rust dhe të përpiqeni të luani me shembuj të ndryshëm. Informacioni i Asamblesë jepet në


Na pëlqeu shumë artikulli "Kritika e gjuhës së ndryshkut dhe pse C/C++ nuk do të vdesë kurrë". Ne i sugjeruam autorit që ta përkthenim artikullin në anglisht dhe gjithashtu ta publikonim në blogun tonë. Ai ra dakord dhe ne jemi të kënaqur ta paraqesim këtë artikull në rusisht dhe anglisht. Artikulli origjinal ndodhet.

Artikulli origjinal është postuar (teksti në Rusisht). Artikulli u publikua në blogun tonë me marrëveshjen e autorit.

Shënim: Në vijim, po supozoj se Rust është një përpjekje për të bërë një gjuhë të shpejtë dhe të sigurt. Në fund të fundit, djemtë e Mozilla-s e bënë atë si një mjet për zhvillimin e motorit të shfletuesit. Nëse kjo është vetëm një gjuhë tjetër thjesht e sigurt, atëherë kemi diçka të çuditshme. Tashmë ka një duzinë gjuhë të ndryshme të sigurta, të gjithë do të gjejnë diçka sipas dëshirës së tyre. Dhe nëse qëllimi nuk është të zëvendësohet C++, atëherë (1) pse është krijuar një nëngrup i pasigurt në gjuhë? (2) pse ishte e nevojshme të hiqeshin rrjedhat e lehta nga gjuha? Me fjalë të tjera, në këtë rast, ajo që po ndodh nuk ka fare kuptim.

Nëse ndodh që po lexoni forumin linux.org.ru, do të vërej se kjo nuk është lista e 10 arsyeve thjesht teknike për të mos pëlqyer Rust që u diskutua në këtë temë. Siç tregohet nga një diskutim në Skype me i dashur shok @sum3rman, ka më shumë se një opinion lidhur me atë se sa “teknike” duhen konsideruar këto arsye. Në përgjithësi, kam bërë një listë të ndyrë, por ndoshta do të rrezikoj ende të citoj disa nga pikat më interesante prej saj. Në fakt, ka shumë arsye të thjeshta, jo teknike këtu.

Fakti që C/C++ nuk do të shkojë askund në të ardhmen e parashikueshme është e qartë për çdo person me mendje të matur. Askush nuk do të rishkruajë pothuajse të gjitha aplikacionet e desktopit, bërthamat e sistemit operativ, përpiluesit, motorët e lojërave dhe shfletuesit, makinat virtuale, bazat e të dhënave, arkivuesit, kodekët audio dhe video, mijëra biblioteka të tjera të bazuara në C, e kështu me radhë. Ky është shumë, shumë kod i shpejtë, i korrigjuar, i testuar me kohë. Rishkrimi i tij është shumë, shumë i shtrenjtë, i rrezikshëm dhe për të qenë i sinqertë, ka kuptim vetëm në vetëdijen e shtrembëruar të vetëm fansave më kokëfortë të Rust Kërkesa për programues C/C++ ka qenë dhe do të jetë e madhe për një kohë shumë të gjatë.

Mirë, po në lidhje me përdorimin e Rust kur shkruani kod të ri?

Kujtojmë se kjo nuk është përpjekja e parë për të bërë një C/C++ “më të saktë”. Le të marrim për shembull gjuhën D. U shfaq në vitin 2001, një gjuhë shumë e mirë. Nuk ka vende të lira pune, nuk ka mjete normale zhvillimi, nuk ka histori suksesi veçanërisht të jashtëzakonshme. Projekti OpenMW fillimisht u shkrua në D, dhe më pas papritmas vendosën ta rishkruajnë atë tërësisht në C++. Siç pranojnë zhvilluesit, ata morën shumë letra në stilin e "projektit të madh, ne do të ishim të lumtur të kontribuonim në të, por ne nuk e dimë dhe nuk duam ta dimë këtë D budallaqe". Wikipedia raporton se përveç D, ka pasur shumë përpjekje të tjera për të vrarë C++ në një shkallë ose në një tjetër, për shembull, Vala, Cyclone, Limbo, BitC. Sa njerëz kanë dëgjuar edhe për gjuhë të tilla?

Mendoj se ka ardhur koha të mësojmë nga historia. Asnjë person i vetëm i arsyeshëm nuk do të tërheqë një gjuhë të re në një projekt derisa të paktën t'i tregoni mjetet normale të zhvillimit, t'i tregoni atij disa histori suksesi dhe t'i tregoni atij një duzinë programues në këtë gjuhë që jetojnë afër. Programuesit, ndoshta, përveç atyre më të rinjve, nuk do ta humbin kurrë kohën dhe shëndetin e tyre për të mësuar gjuhën tjetër më korrekte derisa t'u tregoni mjete normale zhvillimi (jo zanate si Racer), nja dy dhjetëra mijëra biblioteka të gatshme ( jo "eksperimentale", "të paqëndrueshme" e kështu me radhë), mos tregoni disa histori suksesi dhe tregoni një duzinë vendesh të lira të hapura në qytetin e tyre. Problemi me pulën dhe vezët. Shumë rrallë, ky problem mund të zgjidhet me sukses (me kusht, Scala mund të citohet si shembull), kryesisht për shkak të investimit të kohës dhe parave nga ana e disa kompanive të mëdha (Google, Typesafe), për disa arsye të interesuara për të popullarizuar gjuhe.

Siç e kam theksuar tashmë, vetëm arsyet jo-teknike janë më se të mjaftueshme. Megjithatë, thjesht për kuriozitet, le të përpiqemi të imagjinojmë për një sekondë se ata nuk janë aty. Atëherë nuk ka arsye për të mos shkruar në Rust? Rezulton se kjo është gjithashtu të paktën një pyetje shumë e madhe.

C/C++ kritikohet për gjëra të ndryshme. Meqë ra fjala, kritikat bëhen shumë shpesh nga ata që as nga larg nuk e kanë parë kodin C++ në prodhim. Problemi mund të përshkruhet shkurtimisht dhe qartë si më poshtë: C++ është shumë i shpejtë (dhe gjithashtu nuk kërkon memorie, karikimin e baterisë, etj.), por jo i sigurt në kuptimin që ju lejon të shkoni përtej kufijve të grupeve, të aksesoni gabimisht copa të liruara të kujtesës, e kështu me radhë Më tej. Në një kohë, ky problem çoi në shfaqjen e një mase të gjuhëve të sigurta, të tilla si Java, C#, Python dhe të tjera. Por doli që këto gjuhë, në krahasim me C++, janë shumë kërkuese për burime dhe kanë disavantazhe të tjera, për shembull, ndalimin e pashmangshëm të botës gjatë grumbullimit të plehrave. Prandaj, njerëzit po luftojnë me detyrën për të bërë një gjuhë aq të shpejtë sa C++, por edhe të sigurt. Një gjuhë e tillë është Rust.

Ndryshku është me të vërtetë i sigurt, por për fat të keq, ai nuk është i shpejtë. Në kohën e shkrimit, Rust është i krahasueshëm në shpejtësi me Java, Go dhe Haskell:

Unë sinqerisht shpresoj që me kalimin e kohës do të mbingarkohet disi, por deri atëherë, për sa i përket shpejtësisë dhe shkëmbimeve të sigurisë, nuk është shumë më interesante se Scala ose Go. Pyetja mbetet ende e hapur nëse është e mundur që një gjuhë të bëhet fare e shpejtë dhe e sigurt, apo nëse kontrollet e vazhdueshme për tejkalimin e kufijve të grupeve, lidhjet e sigurta rreth lidhjeve me bibliotekat C dhe kështu me radhë e bëjnë automatikisht çdo gjuhë 2 herë më të ngadaltë se C/ C++.

Çfarë saktësisht e bën Rust të sigurt? Me fjalë të thjeshta, është një gjuhë me një analizues të integruar të kodit statik. Një analizues statik vërtet shumë i lezetshëm që kap të gjitha gabimet tipike të C++, jo vetëm ato që lidhen me menaxhimin e kujtesës, por edhe multithreading. Unë kalova një lidhje te një objekt i ndryshueshëm në një lidhje tjetër përmes një kanali dhe më pas u përpoqa ta përdor vetë këtë lidhje - nuk u përpilua. Është vërtet e lezetshme.

Argumenti bëhet shpesh se vetëm 10% e kodit ekzekutohet 90% të rasteve (që, me sa kuptoj, është thjesht një rregull i madh - nuk mund të gjeja shpejt ndonjë kërkim rigoroz mbi këtë temë). Prandaj, shumica e programit mund të shkruhet në Rust të sigurt, me 10% të kodit të nxehtë të shkruar në nëngrupin e pasigurt dhe ngadalësia e zbatimit aktual të Rust nuk është vërtet problem. Ok, por më pas rezulton se Rust nuk nevojitet fare, sepse mund të shkruaj 90% të kodit në Go, dhe 10% në C. Vetëm kërkuesit e plumbave të argjendtë dhe teoricienët pa kontakt do të përdorin Rust vetëm për arsyen se 100% e programit mund të shkruhet në një gjuhë. Edhe pse në realitet këto janë dy dialekte të së njëjtës gjuhë, e cila nuk është aq e ndryshme nga kombinimi i Java plus C ose Go plus C.

Në fakt, rregulli 10:90 është ende një gënjeshtër. Me këtë logjikë, ju mund të rishkruani 90% të WebKit, 90% të VirtualBox ose 90% të GCC në Java dhe të merrni të njëjtin rezultat. Është e qartë se ky nuk është rasti. Edhe nëse çështja nuk është se në një numër programesh ky qëndrim është shumë i ndryshëm, atëherë shikoni duart tuaja. Le të themi se i gjithë programi është shkruar në C/C++ të pasigurt dhe koha e ekzekutimit të tij, duke folur relativisht, është e barabartë me 0.9*1 (një pjesë e vogël e kodit të nxehtë) + 0.1*1 (shumë kod i ftohtë) = 1. Tani le të krahasojeni atë me një program në një gjuhë të sigurt me inserte në Si: 0.9*1 + 0.1*2 = 1.1, afërsisht 10% e diferencës. A është kjo shumë apo pak? Varet nga shkalla juaj. Në rastin e Google, edhe disa për qind mund të kursejnë miliona dollarë (shih pikën 5 në punim, "Përdorimi"). Ose imagjinoni që me përditësimin tjetër, JVM papritmas fillon të kërkojë 10% më shumë burime! Kam frikë edhe të marr me mend se sa zero do të ketë shifra e marrë pas konvertimit të interesit në para amerikane! 10% është shumë në detyrat ku përdoren C dhe C++.

Ne përsërisim "optimizimi i parakohshëm është rrënja e të gjitha të këqijave" si një mantra. Por nëse e marrim fjalë për fjalë, le të përdorim kudo renditjen me flluskë në vend të renditjes së shpejtë. Ne nuk e dimë me siguri se programi do të ngadalësohet në këtë vend të veçantë! Çfarë kuptimi ka të mbështillni numëruesit e zakonshëm të disa veprimeve në memorie aktorësh ose transaksionale nëse mund të përdorni menjëherë atomikun më efikas? Dhe në përgjithësi, në rastet e parëndësishme nuk ka kuptim të inicializosh me forcë të gjitha, të gjitha, të gjitha variablat, të bësh një sërë kontrollesh shtesë, e kështu me radhë. Le të përfundojmë me nxitim jo 10%, por 2-5%. Kjo gjithashtu nuk është aspak e keqe, nëse kërkon vetëm disa minuta më shumë mendim. Dhe siç e kemi kuptuar tashmë, në problemet e zgjidhura në C/C++, kjo mund të jetë një ndryshim i madh! Atëherë, kush tha se gjetja e një pike të nxehtë, rishkrimi i kodit (ndoshta shumë kod) dhe vërtetimi se është vërtet më i shpejtë është më e lehtë sesa të mendosh për performancën paraprakisht?

Nëse ne e shpërfillim çështjen e shkëmbimit të shpejtësisë dhe sigurisë, unë gjithashtu kam pyetje në lidhje me dizajnin e vetë gjuhës. Në veçanti, në lidhje me pesë llojet e treguesve. Nga njëra anë, kjo nuk është e keqe kur programuesi mendon se ku ndodhen variablat, në pirg ose grumbull, dhe nëse disa threads mund ose nuk mund të punojnë me to njëkohësisht. Por nga ana tjetër, imagjinoni që po shkruani një program dhe rezulton se ndryshorja nuk duhet të jetojë në pirg, por në grumbull. Ju rishkruani gjithçka për të përdorur Box. Kështu që ju e kuptoni se ajo që ju nevojitet është Rc ose Arc. Ju rishkruani përsëri. Dhe pastaj ju e rishkruani atë përsëri në një variabël të rregullt në rafte. E gjithë kjo - pa një IDE normale në dorë. Dhe lojërat e rregullta nuk do të ndihmojnë. Epo, ose thjesht në stilin e "Vec" >>>", përshëndetje, Java! Por gjëja më e trishtueshme është se përpiluesi tashmë di për jetëgjatësinë e të gjitha variablave, ai mund të nxjerrë automatikisht të gjitha këto Box, Arc e kështu me radhë. Por për disa arsye kjo pjesë e punës transferohet Për programuesin do të ishte shumë më i përshtatshëm për të shkruar val (në mijëvjeçarin e tretë!), dhe aty ku është e nevojshme, tregoni qartë Box ose Rc në këtë kuptim.

Për shkak të kësaj, në veçanti, fusha e aplikimit të Rust është ngushtuar shumë. Askush në mendjen e tij të drejtë nuk do të shkruante ueb dhe server në një gjuhë të tillë. Sidomos duke pasur parasysh se nuk ofron avantazhe të rëndësishme ndaj të njëjtave gjuhë nën JVM. Dhe Go me fije normale të lehta (jo të ardhme) duket shumë më tërheqëse për këto detyra. Me ardhmërinë, për të mos qëlluar në këmbë, duhet të mësosh të punosh dhe të thuash "gjuhë e sigurt". Po, këto gjuhë kanë karakteristikat e veta, ndalojnë të njëjtën botë, por ky problem mund të zgjidhet si me prerje në mikroshërbime ashtu edhe me teknika të tjera. Dhe po, askush nuk do ta përkthejë Rust në JavaScript, nuk do të shkruajë skripta në të për paraqitje në AWS, ose nuk do ta përdorë atë si një gjuhë pyetjesh për MongoDB. Gjithashtu nuk ka gjasa që ata të shkruajnë për Android, por për një arsye tjetër - ka shumë më shumë se një arkitekturë, dhe është shumë më e lehtë me JVM. Nëse papritmas menduat se Rust ishte "i përshtatshëm për të gjitha detyrat", më duhet t'ju zhgënjej.

Epo, deri në grumbull:

  • Makrot janë një kopje rezervë e fjalës së tepërt të shkaktuar nga mungesa e përjashtimeve normale. Unë kam shkruar tashmë për problemet e metaprogramimit, në veçanti, nuk ka gjasa të shohim një IDE normale për Rust për shkak të tij. Dhe nuk jam i sigurt, por duket se makrot në Rust nuk kanë as hapësira emrash.
  • Njerëzit janë idiotë dhe ngarkesat me të vërtetë inkurajojnë tërheqjen e paketave direkt nga depot e git, duke anashkaluar Crates.io. Si rezultat, ka një probabilitet të lartë për të marrë të njëjtën rrëmujë me paketat si në botën e Erlang me Rabar-in e tij, meqë ra fjala, në botën e Go, duket se është e njëjta situatë.
  • Ashtu si shumë gjuhë të reja, Rust merr rrugën e thjeshtimit. Në përgjithësi, e kuptoj pse nuk ka një trashëgimi normale dhe përjashtime në të, por vetë fakti që dikush vendos gjëra të tilla për mua, lë një shije të pakëndshme. C++ nuk e kufizon programuesin për sa i përket asaj se çfarë duhet të përdorë dhe çfarë jo.
  • Nëse do të ndiqnim rrugën e thjeshtimit, atëherë do të duhej të hidhnim jashtë të gjitha këto zgjerime gjuhësore. Përndryshe, rezulton, si në botën e Haskell-it, secili programues shkruan në dialektin e tij.
  • Treguesit inteligjentë, nëse ka ndonjë gjë, nuk janë aspak të lirë dhe nuk çojnë në kohë të parashikueshme të grumbullimit të plehrave. Një thread befas ka nderin të çlirojë një strukturë shumë të thellë të dhënash. Ndërsa ai ecën nëpër labirintin e hallkave të vdekura, fijet që varen prej tij me durim bëhen budallaqe. I njëjti problem ekziston në Erlang me grupet e tij të vogla, e kam vërejtur vetë më shumë se një herë. Treguesit inteligjentë gjithashtu kanë problemet e tyre, të njëjtin fragmentim të kujtesës dhe rrjedhje. Kam harruar vikpointer në strukturën ciklike, kjo është e gjitha. Dhe kjo në një gjuhë që pretendon të jetë e sigurt. Nëse dëshironi kohë të parashikueshme GC, ose studioni sjelljen e aplikacionit tuaj nën ngarkesë dhe ndërmerrni veprime (kujtoni të njëjtat grupe objektesh) nëse koha GC nuk ju përshtatet, ose menaxhoni kujtesën manualisht.
  • A ka parë dikush një përshkrim rigoroz të semantikës Rust? A ka të paktën një model memorie? Gjithashtu për mua një gjuhë "e sigurt" që "dëshmon korrektësinë" e programeve, e cila në fakt mund të interpretojë kodin burim në dhjetë mënyra të ndryshme, ha!
  • Nuk mund të mos ju kujtoj edhe një herë këtë Problemi janë pothuajse gjithmonë njerëzit, jo teknologjia.. Nëse përfundoni me kod të keq C++ ose Java ngadalësohet papritur, kjo nuk është për shkak se teknologjia është e keqe, por sepse nuk keni mësuar se si ta përdorni atë siç duhet. Do të jeni gjithashtu të pakënaqur me Rust, por për arsye të ndryshme. A nuk do të ishte më e lehtë të mësosh të përdorësh dhe të duash mjete më të njohura?

Në përgjithësi, gjatë 5 viteve të ardhshme më mirë do të investoja kohën time në mësimin e C/C++ sesa Rust. C++ - ky është një standard i industrisë. Një shumëllojshmëri e gjerë problemesh janë zgjidhur me sukses në këtë gjuhë për më shumë se 30 vjet. Dhe Rust dhe të tjerët si ai janë lodra të pakuptueshme me një të ardhme të paqartë. Ka pasur biseda për vdekjen e afërt të C++ që të paktën në vitet 2000, por gjatë kësaj kohe ata kanë filluar të shkruajnë jo më pak në C/C++. Krejt e kundërta. Dhe ne shohim që gjuha po zhvillohet (C++11, C++14), mjete të reja po shfaqen për të (le të kujtojmë CLion dhe Clang), dhe thjesht ka shumë vende të lira përkatëse.

Një programues C++ gjithmonë mund të gjejë lehtësisht një punë me një pagë më shumë se të mirë, dhe nëse është e nevojshme, të rikualifikohet shpejt në Rust. E kundërta është shumë, shumë e dyshimtë. Nga rruga, gjuha, nëse ka asgjë, është larg nga i vetmi dhe jo faktori vendimtar kur zgjedh një vend të ri pune. Për më tepër, një programues me përvojë C/C++ mund të gërmojë lehtësisht në kodin burimor PostgreSQL ose kernel Linux, të përdorë mjete të fuqishme moderne zhvillimi dhe gjithashtu të ketë në dispozicion shumë libra dhe artikuj (të themi, në OpenGL).

Kujdesuni për kohën dhe shëndetin tuaj, nuk keni aq shumë sa mendoni!



Përshëndetje, lexues të dashur!

Jeta nuk qëndron ende, dhe O"Reilly mendoi të botonte librin e parë themelor për gjuhën e programimit Rust:

Pasi u interesuam për këtë temë, vendosëm të sjellim për diskutim përkthimin e një artikulli rishikues rreth gjuhës Rust, botuar në dhjetor 2014. Artikulli është shkurtuar pak për faktin se disa nga pasazhet e tij janë tashmë të vjetruara, por autori e shikon mirë këtë gjuhë në kontekstin e alternativave ekzistuese, duke theksuar avantazhet dhe disavantazhet e saj (të pakushtëzuara).

Sidoqoftë, për ta bërë atë edhe më interesant, le të lëmë në komentet e këtij artikulli një lidhje me një artikull tjetër rreth Rust, të botuar në një nga bloget tona të preferuara të programimit në gjuhën ruse. Për të filluar, shkoni te mace.

Mohim përgjegjësie: Shija për gjuhët e programimit është një çështje shumë subjektive, ashtu si ky postim. Merreni me skepticizëm të shëndetshëm.

Kohët e fundit janë shfaqur disa gjuhë të reja programimi. Midis tyre më interesonte veçanërisht Rust. Më poshtë do të ndaj përshtypjet e mia për Rust dhe do ta krahasoj atë me disa gjuhë të tjera programimi.

Pengesë për të mësuar Rust

Nuk e njoha Rust në provën time të parë. Ka disa pengesa për të mësuar këtë gjuhë, duke përfshirë:

  1. Gjuha po ndryshon me shpejtësi. Nuk ka asnjë "diktator të mirë për jetën" në Rust. Gjuha evoluon përmes kontributeve të anëtarëve të ekipit kryesor dhe komunitetit.
  2. Duke marrë parasysh pikën e parë, Udhëzimet e ndryshkut janë shumë të rralla. Ekziston një manual, dokumentacion tjetër zyrtar dhe faqja Rust by Example janë burime të shkëlqyera. Sidoqoftë, Rust është shumë më kompleks. Shpesh ju duhet të pastroni RFC-të, bloget dhe madje edhe komentet në Github për të gjetur informacionin që ju nevojitet, dhe edhe nëse ky informacion u shfaq vetëm dje, ju ende nuk jeni plotësisht të sigurt për të. Pres me padurim një libër të mirë dhe autoritar mbi Rust, megjithëse vë bast se do të jetë i gjatë.
  3. Sistemi i pronësisë së Rust dhe mekanizmi i kontrollit të huamarrjes mund të jenë konfuzë për fillestarët. Për të garantuar sigurinë e kujtesës pa grumbullimin e mbeturinave, Rust përdor një sistem të ndërlikuar huamarrjeje dhe pronësie. Ajo shpesh i tremb neofitët.
  4. Përpiluesi Rust është shumë i rreptë. Unë e quaj Rust një gjuhë disipline. Çdo gjë që nuk është plotësisht e dukshme për përpiluesin Rust duhet të specifikohet vetë, dhe disa nga qëllimet tuaja ju vetë mund të mos i dini në fillim. Kjo pengesë mësimore, së bashku me të gjitha të tjerat, shpesh rezulton në një përshtypje të parë dekurajuese të Rustit.

Përparësitë

Ndryshku ka shumë përparësi. Disa prej tyre janë unike.

Siguria e memories pa grumbullimin e mbeturinave

Kjo është ndoshta arritja më e rëndësishme e Rust. Në gjuhët e programimit të nivelit të ulët që lejojnë manipulimin e drejtpërdrejtë të memories, gabimet si përdorimi pas pa pagesë ose rrjedhjet e kujtesës në kohën e ekzekutimit janë mjaft të shtrenjta. Në C++ moderne, aftësia për t'u marrë me gjëra të tilla është përmirësuar, por kërkon një disiplinë të rreptë teknike (lexo: programuesit vazhdojnë të kryejnë operacione të pasigurta). Prandaj, për mendimin tim, në përgjithësi, C ++ nuk mund ta zgjidhë rrënjësisht dhe me besueshmëri këtë problem.

Është e vërtetë që programuesit e Rust mund të shkruajnë kod të pasigurt në një bllok të pasigurt, por (1) kjo bëhet me qëllim dhe (2) blloqet e pasigurta mund të përbëjnë vetëm një pjesë shumë të vogël të të gjithë bazës së kodit, por ato kontrollohen rreptësisht.
Mbledhësi i mbeturinave është mjeti më i zakonshëm i sigurisë së kujtesës. Nëse shkoni mirë me GC, atëherë keni mjaft opsione. Sidoqoftë, sistemi i pronësisë së Rust siguron jo vetëm sigurinë e kujtesës, por edhe sigurinë e të dhënave dhe burimeve (shih më poshtë)

RAII dhe burimet

RAII (përvetësimi i burimeve është inicializimi) është një term i çuditshëm, por ai e përcjell mirë idenë. Në Wikipedia lexojmë se RAII punon me objekte të alokuara në rafte. Sistemi i pronësisë së Rust lejon që ky parim të zbatohet edhe për objektet e alokuara nga grumbulli. Kjo e bën lëshimin automatik të burimeve - për shembull, memorie, skedarë, priza - shumë të parashikueshme dhe të garantuara në kohën e përpilimit.
Gjuhët dinamike si Python ose Ruby kanë aftësi të ngjashme, por ato nuk përputhen me fuqinë e Rust IMO.

Konkurrueshmëria pa gara të dhënash

Rust siguron sigurinë e të dhënave gjatë programimit të njëkohshëm - domethënë, siguron që vetëm shumë lexues ose një "shkrimtar" mund t'i qasen të dhënave në çdo kohë të caktuar.

Lloji i të dhënave algjebrike

Përveç llojeve të rregullta (tupa dhe struktura), Rust ofron gjithashtu lloje të numërimit (këtu të quajtur "llojet e shumave" ose "llojet e varianteve") dhe përputhjen e modeleve. Është për t'u habitur që një gjuhë programimi sistemesh ka një sistem të tillë të zhvilluar.

Përbërja mbi trashëgiminë

Ndryshku favorizon qartë përbërjen e tipit mbi trashëgiminë. Jam në kampin ku ky fakt konsiderohet si fitore. Kur Rust mbështet llojet gjenerike, tiparet luajnë një rol kyç.

Disavantazhet (të kushtëzuara)

Gjithçka duhet të jetë shumë e qartë

Ndryshku është një gjuhë e disiplinuar. Përpiluesi duhet të komunikojë gjithçka shumë qartë, ose do të betohet derisa të mos ketë mbetur asnjë pikë e paqartë. Kjo përgjithësisht përfiton cilësinë e kodit, por mund të jetë e tepërt kur bëhet fjalë për prototipimin e shpejtë ose detyrat e njëhershme.

Si rezultat: duhet të shkruani kod më të mirë dhe më të qartë në Rust. Pasi ta kuptoni këtë, skajet e vrazhda pak a shumë mund të zhduken.

Mbledhja e mbeturinave është dytësore

Rust ka një grumbullues shumë themelor mbeturinash: Rc, një numërim referencë dhe Arc, një numërim referimi atomik pa zbulim të rrumbullakët. Megjithatë, këto veçori nuk funksionojnë në gjuhë si parazgjedhje dhe do t'ju duhet të përdorni më shpesh mekanizmat standardë të menaxhimit të kujtesës të Rust (Stack, &, dhe Box). Nëse problemet e kujtesës në aplikacionin tuaj nuk janë të rëndësishme, atëherë do t'ju duhet të toleroni modelin e sigurisë së kujtesës Rust, i cili nuk përdor mbledhjen e mbeturinave.

Ekspresiviteti nuk është qëllim në vetvete

Gjuha Rust nuk shqetësohet për ekspresivitetin ose bukurinë e kodit. Padyshim që nuk është keq në këtë drejtim, por nuk është aq e mrekullueshme sa mund të dëshironit të jetë.

Barrierë relativisht e lartë për hyrjen

Në parim, Rust nuk është një nga ato gjuhë që mund të zotëroni shpejt dhe të shkruani kodin profesional brenda disa javësh. Rust është ndoshta më kompakt se C++, por është padyshim më i madh se shumë gjuhë programimi. Në krahasim me gjuhët e tjera, nuk mund të quhet shumë e aksesueshme. Ky mund të jetë problem nëse përparësia juaj është shpejtësia e përvetësimit të gjuhës.

Rust dhe gjuhë të tjera

Gjuhët dinamike

Gjuhët dinamike (skriptuese) janë në skajin e kundërt të spektrit të gjuhës së programimit nga Rust. Krahasuar me Rust, shkrimi i kodit në gjuhë dinamike është zakonisht më i shpejtë dhe më i lehtë. Unë mendoj se gjuhët dinamike mundin Rust në këto situata:

  • Prototipizim i shpejtë ose detyra të njëhershme
  • Kodi nuk është për prodhim, ose ai ku një gabim në kohën e ekzekutimit është një problem i vogël
  • Projekti vetanak (individual).
  • Puna gjysmë automatike (p.sh. analiza/analiza e regjistrave, përpunimi i tekstit në grup)

Në raste të tilla, nuk duhet të përpiqeni të bëni gjithçka në mënyrë perfekte. Përkundrazi, Rust, për mendimin tim, është më i përshtatshëm për:

  • Punoni në një ekip të mesëm ose të madh
  • Kodi i orientuar për përdorim afatgjatë në prodhim
  • Kodi që do të përdoret për një kohë të gjatë kërkon mirëmbajtje të rregullt dhe/ose rifaktorim
  • Kodi që do të shkruani shumë teste të njësisë për të garantuar sigurinë

Në përgjithësi, kur cilësia e kodit është kritike. Gjuhët dinamike ju ndihmojnë të shkruani kodin më shpejt në fazën fillestare, por më vonë puna ngadalësohet: duhet të shkruani më shumë teste, linja e zhvillimit ndërpritet ose edhe ndodhin ndërprerje në prodhim. Përpiluesi Rust ju detyron të bëni shumë gjëra në mënyrë korrekte në kohën e përpilimit, kur është më pak e kushtueshme për të identifikuar dhe rregulluar gabimet.

Shkoni

Krahasimi i këtyre dy gjuhëve është një arsye e shkëlqyeshme për të argumentuar, por duke qenë se kam disa kohë që studioj, do të ndaj përsëri këtu përshtypjet e mia subjektive për të. Krahasuar me Rust, ja çfarë më pëlqen tek Go:

  • e lehtë - gjuha është e vogël (dhe e thjeshtë, por shumë e fuqishme)
  • utility gofmt – zvogëlon ndjeshëm ngarkesën mendore gjatë programimit
  • gorutinë/kanal
  • Kompilim i menjëhershëm

Pse u largova nga Go:

  • Është shumë minimaliste. Sistemi i tipit dhe vetë gjuha nuk janë shumë të zgjerueshme
  • Programimi Go më duket pak i thatë. Më kujton ditët kur programoja në Java: e mirë për zhvillimin e ndërmarrjes, mekanike dhe... jo aq interesante (kujtesë: nuk ka diskutim për shijet)
  • Popullariteti i Go vazhdon falë mbështetjes së Google, por kjo më bën pak skeptik. Kur interesat e komunitetit dhe të kompanisë nuk përkojnë, i pari mund të sakrifikohet. Sigurisht, çdo kompani kryesisht ndjek interesat e veta. Nuk ka asgjë të keqe. Është thjesht... pak e bezdisshme. (Shumë gjuhë dhe korniza të promovuara nga korporatat përballen me një problem të ngjashëm. Të paktën Mozilla nuk varet nga çmimet e aksioneve.)

Nim

Nim (i quajtur më parë Nimrod) është një gjuhë shumë interesante. Përpilohet në C, kështu që performanca është mjaft e mirë. Nga pamja e jashtme, ajo i ngjan Python, një gjuhë në të cilën më ka pëlqyer gjithmonë programimi. Është një gjuhë e mbledhur nga mbeturinat, por ofron mbështetje të butë në kohë reale dhe sjellja e vetë grumbulluesit të plehrave është më e parashikueshme. Ka një sistem efektesh interesante. Në parim, më pëlqen shumë kjo gjuhë.

Problemi më i madh në rastin e tij është papjekuria e ekosistemit. Gjuha në vetvete është e dizajnuar mirë dhe relativisht e qëndrueshme, por aktualisht kjo nuk është aq afër sa për një gjuhë programimi të ketë sukses. Dokumentacioni, bibliotekat standarde, depot e paketave, kornizat mbështetëse, komuniteti dhe pjesëmarrja e palëve të treta... përgatitja e të gjithave për prodhim nuk është e lehtë.

Pa specialistë për të përfunduar gjuhën me kohë të plotë, kjo fazë e fundit mund të jetë shumë rraskapitëse. Ndër gjuhët e reja të programimit, Nim ende nuk mund të mburret me mbështetje serioze.
E thënë kështu, i uroj suksese dhe vazhdoj ta ndjek.

Të tjerët

Ka gjuhë të tjera si Julia dhe . Julia është një gjuhë dinamike me performancë të mirë dhe thirrje të buta në stilin C (Nëse ju pëlqejnë gjuhët dinamike dhe REPL, kushtojini vëmendje). Julia ka fituar vëmendjen e të gjithëve falë fushave të saj numerike dhe shkencore. Ndërsa ajo ka potencialin të bëhet një gjuhë me qëllim të përgjithshëm, më duket se zhvillimi i një gjuhe ndikohet shumë nga bashkësia e krijuesve të saj.

D, të paktën fillimisht, ishte një përpjekje për të krijuar "C++, por më mirë." Versioni i tij 1.0 u lëshua në 2007, kështu që kjo gjuhë nuk është aq e re. Kjo është një gjuhë e mirë, por për arsye objektive ende nuk ka zënë rrënjë: arsyeja është ndarja në Phobos/Tango në një fazë të hershme dhe sigurimi i sigurisë së kujtesës kryesisht përmes grumbullimit të mbeturinave dhe pozicionimi fillestar si zëvendësim për C++.

Pse mendoj se shanset e Rustit janë shumë të larta

Ka kaq shumë gjuhë të reja programimi që dalin këto ditë. Çfarë, sipas mendimit tim, e bën Rustin të dallohet mes tyre? Unë do të jap argumentet e mëposhtme:

Një gjuhë e vërtetë për programimin e sistemeve

Përfshirja nuk është një detyrë e lehtë. Ndoshta mund të zgjidhet fjalë për fjalë në disa gjuhë, ose edhe vetëm në dy: C dhe C++. (Kjo mund të jetë arsyeja pse Skylight zgjodhi Rust për të zhvilluar një shtesë për Ruby, edhe pse ishte jashtëzakonisht e rrezikshme.) Është e jashtëzakonshme se sa mirë Rust ka arritur të eliminojë shpenzimet e përdorimit. Kjo hap një perspektivë unike për Rust.

Pa Null

Objekti/treguesi null (i ashtuquajturi "bug miliardë dollarësh") është një burim i zakonshëm i gabimeve në kohën e ekzekutimit. Ka vetëm disa gjuhë programimi që nuk kanë null, kryesisht gjuhë funksionale. Çështja është se për të hequr qafe null kërkon një sistem të tipit shumë të avancuar. Në mënyrë tipike, trajtimi i kësaj në nivelin sintaksor të gjuhës kërkon një lloj të dhënash algjebrike dhe përputhje modeli.

Gjuhë e nivelit të ulët me konstruksione të avancuara të nivelit të lartë

Duke qenë një "gjuhë metalike e zhveshur" deri në thelb (të paktën në teori), Rust ofron gjithashtu shumë karakteristika të nivelit relativisht të lartë, duke përfshirë llojin e të dhënave algjebrike, përputhjen e modelit, tiparin, konkluzionet e tipit, etj.

Komunitet i fortë dhe rëndësi praktike

Komuniteti Rust është shumë miqësor dhe aktiv. (Sigurisht, kjo është një përshtypje subjektive). Përveç kësaj, Rust është përdorur në disa projekte serioze praktike - në veçanti, përpiluesi Rust, Servo, Skylight, etj. ende në fazën e zhvillimit të gjuhës.

Deri më tani - nuk ka gabime të mëdha

Ndonjëherë, zhvillimi i një gjuhe ose kuadri i kryer brenda një kompanie mund të arrijë aksidentalisht në një rrugë pa krye. Për fat të mirë, ekipi kryesor i Rust po bën një punë të shkëlqyer deri më tani. Vazhdo kështu, Rust!

Rust për zhvillimin e uebit

Nëse Rust është një gjuhë programimi sistemesh, a është e përshtatshme për zhvillimin e uebit? Po kërkoj një përgjigje edhe për këtë pyetje.

Bibliotekat dhe kornizat

Para së gjithash, disa biblioteka HTTP duhet të jenë gati për këtë. (Kjo përshkruhet në faqen e internetit "A jemi ende në internet"). Biblioteka e parë rust-http është tashmë e vjetëruar; pasardhësi i saj i mundshëm Teepee është praktikisht në animacion të pezulluar. Për fat të mirë, Hyper duket si një kandidat i mirë. Është pranuar tashmë në Servo, një projekt simbiotik i Rust, të cilin e konsideroj një bekim të jetë biblioteka HTTP për Rust.

Biblioteka standarde Rust nuk mbështet ende hyrje/dalje asinkrone. Për këtë qëllim, mund të përdorni bibliotekën e jashtme mio, e cila ofron prizë jo-bllokuese I/O. Mbështetja e fijes së gjelbër është hequr si pjesë e thjeshtimit të I/O.

Disa korniza ueb për Rust janë duke u zhvilluar në mënyrë aktive, duke përfshirë Iron dhe nickel.rs. Mund të duhet kohë përpara se situata me ta të qetësohet.

A është Rust një gjuhë për ueb?

Një ditë bibliotekat dhe kornizat do të jenë gati. Pyetja është, a është vetë Rust i përshtatshëm për zhvillimin e uebit? A janë shumë komplekse menaxhimi i memories së nivelit të ulët dhe veçoritë e sigurisë së Rust?

Mendoj se në fund gjithçka varet nga ajo që prisni nga projekti. Më lart, kur krahasoja Rust me gjuhët dinamike në projekte afatshkurtra, përmenda se në raste të tilla, kompleksiteti i Rust mund të jetë i pajustifikuar. Por nëse prisni që produkti të zgjasë një kohë të gjatë - të themi, gjashtë muaj ose më shumë - atëherë Rust mund të jetë një opsion i mirë.

A është Rust i mirë për startup-et në internet?

Po startup-et? Ato kërkojnë cikle të shpejta prototipizimi dhe zhvillimi. Kjo është një pyetje më e diskutueshme, por unë i qëndroj mendimit tim: nëse po shikoni një projekt afatgjatë, atëherë zgjedhja e gjuhës së duhur të programimit është e rëndësishme dhe Rust meriton vëmendje të veçantë. Nga perspektiva e biznesit, një gjuhë që mundëson prototipimin e shpejtë ofron përfitime të konsiderueshme, ndërsa rifaktorimi dhe eliminimi i pengesave mund të lihet gjithmonë për më vonë. Realiteti inxhinierik është se kostoja e punës së rifaktorimit është zakonisht më e lartë se sa duket, dhe edhe nëse shkundni shumë elementë të sistemit tuaj, kodi i shkruar shumë kohë më parë do të mbetet ende në një cep. Për shumë vite.

Provoni Rust!

Ju mund të ndihmoni dhe transferoni disa fonde për zhvillimin e faqes



Artikujt më të mirë mbi këtë temë