Bedste svar
Syntaktisk sukker, eller syntaks sukker, er en visuel eller logisk tiltalende “genvej” leveret af sproget, som reducerer mængden af kode, der skal skrives i en almindelig situation.
For eksempel, når du indstiller en variabel til en værdi, der er afhængig af en betingelse, på et enklere sprog med mindre “sukker” kan du muligvis gøre dette:
int a;
if(SomeFunction() == 2)
a = 4;
else
a = 9;
Dette er lidt meget for en så enkel operation; på enklere sprog oprettede udviklere ofte en “Inline If” -funktion for at indpakke denne logik i noget mere koncist:
public T Iif
{
if(condition) return ifTrue;
return ifFalse;
}
...
//usage
int a = Iif(SomeFunction() == 2, 4, 9);
Der er nu den faktiske brug meget mere kortfattet. Mange moderne sprog inklusive C # inkorporerer en operation som denne direkte i sprogspecifikationen i form af den “ternære betingede operator”:
int a = SomeFunction() == 2 ? 4 : 9;
Denne operatør er sprogbaseret “syntaks sukker” til en betinget operation.
Nu er et almindeligt undertilfælde af denne betingede variabelindstilling, at hvis vores første valg for et middel til at producere en værdi for at indstille til variablen evalueres som nul, skal vi bruge et alternativt middel. For eksempel:
MyClass theClass = GetMyClass();
if(theClass == null)
theClass = FailSafeMyClassGetter();
Ikke dårligt, men det kan vi forbedre:
MyClass theClass = GetMyClass() ?? FailSafeMyClassGetter();
“??” operator er kendt som “null-coalescing operator”, og den producerer grundlæggende den første værdi som læst fra venstre mod højre, der ikke er null.
En anden, C # fik for nylig, var “auto-egenskaben”. Kortfattet har C # det, der kaldes “egenskaber”; par kodeblokke, der repræsenterer et “data-medlem” af et objekt, der kan udføre mere kompleks validering eller beregningslogik end et simpelt felt kunne, men der kan tilgås som om medlemmet var et felt i stedet for at bruge GetX () og SetX () metodeopkald, så det bliver let at skelne i kode, når du får adgang til data i forhold til udførelse af operationer. Det er bedste praksis i C # af konsistens og vedligeholdelsesmæssige grunde at bruge egenskaber i stedet for felter, når du implementerer offentligt synlige datamedlemmer . Men ni gange ud af ti indpakker ejendommen bare en privat feltvariabel, og efter bedste praksis kan ejendomsimplementeringen til en simpel dataværdi se ud:
private int \_myIntProperty;
public int MyIntProperty
{
get
{
return \_myIntProperty;
}
set
{
\_myIntProperty = value;
}
}
Slags grimme, meget gentagne og langt flere linjer med kode, end vi virkelig har brug for. Det var fristende tidligere at give afkald på bedste praksis og brug bare et felt i disse enkle tilfælde, så for at reducere den fristelse og den skadelige virkning, det kan have på kodebasen, hvis du senere besluttede, at du virkelig havde brug for en ejendom, inkluderede C # s designere noget syntaks sukker i C # 3.0 specifikation:
public int MyIntProperty { get; set; }
Denne ejendomserklæring behandles som den samme som ovenstående erklæring, men det er meget hurtigere og lettere at skrive en klasse fuld af disse end at gøre det på den gamle måde, og det er også meget lettere at vedligeholde.
Dette er blot et par eksempler på “syntaks sukker” tilgængelig i C #. Andre inkluderer:
* Variabel type slutning – var someInt = 5;
– Compileren kan bestemme typen af en erklæret lokal variabel fra den oprindelige opgave, så du ikke har for eksplicit at specificere det (og derefter ændre det, hvis den type, du har brug for, ændres).
* yield return
– En masse .NET-programmering involverer samlinger af objekter og udfører gentagne opgaver på hvert element af samme. Det plejede at være en ganske involveret proces at implementere IEnumerable
interface, der tillader forskellige indbyggede sløjfer som foreach
for at fungere, hvilket kræver en hel anden klasse, der implementerede IEnumerator
for at håndtere iterering gennem samlingen. Nøgleordet yield return
forenklede dramatisk det ved at lade selve iteratorlogikken defineres i samlingens egen GetEnumerator () metode.
* async
/ await
– Tilsvarende skal flere og flere programmeringsopgaver køres “asynkront” ved at give arbejde til en anden “tråd” i applikationen, så programmets arbejde kan opdeles mellem flere processorer i den moderne pc, mens brugergrænsefladen til applikationen forbliver “lydhør” til anmodninger fra operativsystemet om at tegne brugergrænsefladen og udføre andre visuelle opgaver. Begrebet trådning er ikke svært at forstå, men indtil C # 4.0 krævede det i det væsentlige at opdele din metode i to; en metode starter den asynkrone operation, derefter kaldes en anden, når baggrundstråden er færdig med arbejdet. Ikke mere; disse to nye nøgleord tillader, at en funktion, der udfører asynkront arbejde, kan defineres meget synkront, mens kompilatoren gør metodens opdeling bag kulisserne, når man bygger koden.
Svar
Der er ingen formel definition af syntaktisk sukker, dette er en tåget forestilling.
Syntaktisk sukker i sin mest accepterede definition er ekstra syntaks, der straks oversættes til en mere primitiv og besværlig form af kompilatoren, men tillader en “sødere” oplevelse for programmøren med at udtrykke visse almindelige instruktioner.
Problemet med denne definition er, at “ekstra” syntaks ikke er en meget meningsfuld beskrivelse. I visse tilfælde er det ret klart, at vi har syntaktisk sukker, for eksempel definerer Haskells sprograpport eksplicit visse syntaktiske elementer (do-blokke og listeforståelser) ved deres oversættelse i en enklere syntaks. Dette er et ret tydeligt tilfælde af syntaktisk sukker, de findes kun for at lette skrivningen af et program, ikke i nogen dyb forstand i oversætteren af programmet til et symbolsk træ.
I andre tilfælde, det er meget mindre klart, fordi sproget ikke gider med denne form for formalisering, for eksempel er dekoratører i Python ofte beskrevet af, hvordan du ville skrive den tilsvarende kode uden dem, men så vidt jeg ved, bliver det aldrig udtrykkeligt sagt: “du bør ikke kompilere dekoratører direkte i din mellemrepræsentation, men snarere oversætte dem på denne måde på forhånd ”. En del implementering af Python kan vælge at gøre netop det, men andre kan have tilføjet dekoratører som en funktion af deres mellemrepræsentation.