Beste svaret
Syntaktisk sukker, eller syntaks sukker, er en visuelt eller logisk tiltalende «snarvei» gitt av språket, som reduserer mengden kode som må skrives i noen vanlige situasjoner.
For eksempel når du setter en variabel til en verdi som er avhengig av en tilstand, på et enklere språk med mindre «sukker» kan du gjøre dette:
int a;
if(SomeFunction() == 2)
a = 4;
else
a = 9;
Dette er litt mye for en så enkel operasjon; på enklere språk opprettet utviklere ofte en “Inline If” -funksjon for å pakke denne logikken inn i noe mer kortfattet:
public T Iif
{
if(condition) return ifTrue;
return ifFalse;
}
...
//usage
int a = Iif(SomeFunction() == 2, 4, 9);
Der er nå den faktiske bruken mye mer kortfattet. Mange moderne språk, inkludert C #, inkluderer en operasjon som dette direkte i språkspesifikasjonen i form av «ternary conditional operator»:
int a = SomeFunction() == 2 ? 4 : 9;
Denne operatøren er språkbasert «syntaks sukker» for en betinget operasjon.
Nå er et vanlig undertilfelle for denne betingede variabelinnstillingen at hvis vårt førstevalg for et middel til å produsere en verdi for å sette til variabelen evalueres som null, bør vi bruke et alternativt middel. For eksempel:
MyClass theClass = GetMyClass();
if(theClass == null)
theClass = FailSafeMyClassGetter();
Ikke dårlig, men det kan vi forbedre:
MyClass theClass = GetMyClass() ?? FailSafeMyClassGetter();
«??» operator er kjent som «null-koalescerende operator» og den produserer i utgangspunktet den første verdien som er lest fra venstre til høyre som ikke er null.
En annen C # fikk nylig var «auto-egenskapen». Kortfattet har C # det som kalles «egenskaper»; par kodeblokker som representerer et «data-medlem» av et objekt, som kan utføre mer kompleks validering eller beregningslogikk enn et enkelt felt kunne, men som kan nås som om medlemmet var et felt i stedet for å bruke GetX () og SetX () metodeanrop, så det blir lett å skille i kode når du får tilgang til data i forhold til å utføre operasjoner. Det er best praksis i C #, av konsistens og vedlikeholdsårsaker, å bruke egenskaper i stedet for felt når du implementerer offentlig synlige datamedlemmer . Imidlertid, «innpakker» eiendommen «bare» en privat feltvariabel ni ganger av ti, og etter beste praksis kan eiendomsimplementeringen for en enkel dataverdi se ut som:
private int \_myIntProperty;
public int MyIntProperty
{
get
{
return \_myIntProperty;
}
set
{
\_myIntProperty = value;
}
}
Slags stygg, veldig repeterende og langt flere kodelinjer enn vi virkelig trenger. Det var fristende tidligere å gi avkall på beste praksis og bare bruk et felt i disse enkle tilfellene, så for å redusere den fristelsen og den skadelige effekten den kan ha på kodebasen hvis du senere bestemte deg for at du virkelig trengte en eiendom, inkluderte C # s designere litt syntaks sukker i C # 3.0 spesifikasjon:
public int MyIntProperty { get; set; }
Denne eiendomserklæringen behandles som den samme som den ovennevnte erklæringen, men det er mye raskere og lettere å skrive en klasse full av disse enn å gjøre det på den gamle måten, og det er mye lettere å vedlikeholde det også.
Dette er bare et par eksempler på «syntaks sukker» tilgjengelig i C #. Andre inkluderer:
* Inferens av variabel type – var someInt = 5;
– Kompilatoren kan bestemme typen av en deklarert lokal variabel fra den første tildelingen, slik at du ikke har for å spesifisere det eksplisitt (og deretter endre det hvis typen du trenger endres).
* yield return
– Mye .NET-programmering innebærer samlinger av objekter, og gjør gjentatte oppgaver på hvert element av det samme. Det pleide å være en ganske involvert prosess for å implementere IEnumerable
grensesnitt som tillater forskjellige innebygde sløyfer som foreach
for å fungere, og krever en hel andre klasse som implementerte IEnumerator
for å håndtere iterering gjennom samlingen. yield return
nøkkelordet forenklet dramatisk det, ved å la selve iteratorlogikken bli definert i samlingens egen GetEnumerator () -metode.
* async
/ await
– Tilsvarende må flere og flere programmeringsoppgaver kjøres «asynkront» ved å gi jobbe til en annen «tråd» av applikasjonen, slik at arbeidet til programmet kan deles mellom flere prosessorer i den moderne PCen, mens brukergrensesnittet til applikasjonen forblir «lydhør» på forespørsler fra operativsystemet om å tegne UI og utføre andre visuelle oppgaver. Konseptet med threading er ikke vanskelig å forstå, men inntil C # 4.0 krevde det egentlig å dele metoden din i to; en metode starter den asynkrone operasjonen, deretter kalles en sekund når bakgrunnstråden er ferdig med arbeidet. Ikke mer; disse to nye nøkkelordene gjør det mulig å definere en funksjon som gjør asynkront arbeid på en veldig synkron måte, mens kompilatoren gjør metodedeling bak kulissene når man bygger koden.
Svar
Det er ingen formell definisjon av syntaktisk sukker, dette er en nebuløs forestilling.
Syntaktisk sukker i sin mest aksepterte definisjon er ekstra syntaks som umiddelbart oversettes til en mer primitiv og tungvint form av kompilatoren, men tillater en «søtere» opplevelse for programmereren i å uttrykke visse vanlige instruksjoner.
Problemet med denne definisjonen er at «ekstra» syntaks ikke er en veldig meningsfull beskrivelse. I visse tilfeller er det ganske klart at vi har syntaktisk sukker, for eksempel definerer Haskells språkrapport eksplisitt visse syntaktiske elementer (do-blokker og listeforståelser) ved deres oversettelse i en enklere syntaks. Dette er et ganske klart tilfelle av syntaktisk sukker, de eksisterer bare for å lette skrivingen av et program, ikke i noen dyp forstand i oversetteren av programmet til et symbolsk tre.
I andre tilfeller, det er mye mindre klart fordi språket ikke bryr seg med denne typen formalisering, for eksempel blir dekoratører i Python ofte beskrevet av hvordan du ville skrevet den tilsvarende koden uten dem, men så vidt jeg vet blir det aldri eksplisitt sagt: “du skal ikke kompilere dekoratører direkte i din mellomrepresentasjon, men snarere oversette dem på denne måten på forhånd ”. Noen implementeringer av Python kan velge å gjøre nettopp det, men andre kan ha lagt til dekoratører som en funksjon av deres mellomrepresentasjon.