Co to jest cukier syntaktyczny w językach programowania?

Najlepsza odpowiedź

Cukier syntaktyczny lub cukier składniowy to atrakcyjny wizualnie lub logicznie „skrót” zapewniany przez język, zmniejsza ilość kodu, który trzeba napisać w jakiejś typowej sytuacji.

Na przykład, ustawiając zmienną wartość zależną od warunku, w prostszym języku z mniejszą ilością „cukru” możesz to zrobić to:

int a;

if(SomeFunction() == 2)

a = 4;

else

a = 9;

To trochę za dużo jak na tak prostą operację; w prostszych językach programiści często tworzyli funkcję „Inline If”, aby opakować tę logikę w coś bardziej zwięzłego:

public T Iif(bool condition, T ifTrue, T ifFalse)

{

if(condition) return ifTrue;

return ifFalse;

}

...

//usage

int a = Iif(SomeFunction() == 2, 4, 9);

Teraz rzeczywiste użycie jest znacznie bardziej zwięzłe. Wiele współczesnych języków, w tym C #, zawiera taką operację bezpośrednio w specyfikacji języka w postaci „trójskładnikowego operatora warunkowego”:

int a = SomeFunction() == 2 ? 4 : 9;

Ten operator jest dostarczonym przez język „cukrem składniowym” dla operacji warunkowej.

Powszechnym przypadkiem podrzędnym tego warunkowego ustawienia zmiennej jest to, że jeśli nasz pierwszy wybór środka do wytworzenia wartości aby ustawić na zmienną daje wartość null, powinniśmy użyć alternatywnych środków. Na przykład:

MyClass theClass = GetMyClass();

if(theClass == null)

theClass = FailSafeMyClassGetter();

Nieźle, ale możemy to poprawić:

MyClass theClass = GetMyClass() ?? FailSafeMyClassGetter();

Znak „??” operator jest znany jako „operator łączący wartości null” i generuje w zasadzie pierwszą wartość odczytywaną od lewej do prawej, która nie jest null.

Inną ostatnio otrzymaną C # była „właściwość auto”. Krótko mówiąc, C # ma tak zwane „właściwości”; pary bloków kodu, które reprezentują „składową danych” obiektu, które mogą wykonywać bardziej złożoną logikę walidacji lub obliczeń niż proste pole, ale można uzyskać do nich dostęp tak, jakby element członkowski był polem zamiast używania GetX () i SetX (), dzięki czemu łatwo jest rozróżnić kod, gdy ponownie uzyskujesz dostęp do danych, a nie wykonujesz operacji. Najlepszą praktyką w języku C #, ze względu na spójność i konserwację, jest używanie właściwości zamiast pól podczas implementowania publicznie widocznych elementów członkowskich danych . Jednak dziewięć razy na dziesięć właściwość „po prostu„ opakowuje ”zmienną pola prywatnego, więc zgodnie ze sprawdzonymi metodami implementacja właściwości dla prostej wartości danych może wyglądać następująco:

private int \_myIntProperty;

public int MyIntProperty

{

get

{

return \_myIntProperty;

}

set

{

\_myIntProperty = value;

}

}

Trochę brzydki, bardzo powtarzalny i o wiele więcej wierszy kodu, niż naprawdę potrzebujemy. W przeszłości kuszono, by zrezygnować najlepsza praktyka i po prostu użyj pola w tych prostych przypadkach, aby zmniejszyć tę pokusę i szkodliwy wpływ, jaki może mieć na podstawę kodu, jeśli później zdecydujesz, że naprawdę potrzebujesz właściwości, projektanci C # włączyli trochę cukru składniowego do C # 3.0 specyfikacja:

public int MyIntProperty { get; set; }

Ta deklaracja właściwości jest traktowana jako taka sama jak powyższa deklaracja, ale znacznie szybciej i łatwiej napisać jest ich pełnych, niż zrobić to w stary sposób, a także o wiele łatwiejsze w utrzymaniu.

To tylko kilka przykładów „cukru składniowego” dostępnego w C #. Inne obejmują:

* Wnioskowanie o typie zmiennej – var someInt = 5; – Kompilator może określić typ zadeklarowanej zmiennej lokalnej na podstawie początkowego przypisania, więc nie musisz aby jawnie go określić (a następnie zmienić, jeśli typ, który chcesz zmienić).

* yield return – Wiele programów .NET obejmuje kolekcje obiektów i wykonywanie powtarzalnych zadań na każdym elemencie tego samego. Wdrażanie interfejsu IEnumerable, który umożliwia różne wbudowane pętle, takie jak foreach do obsługi iteracji w kolekcji. Słowo kluczowe yield return znacznie to uprościło, pozwalając na zdefiniowanie samej logiki iteratora w ramach własnej metody GetEnumerator () kolekcji.

* async / await – Podobnie coraz więcej zadań programistycznych musi być wykonywanych „asynchronicznie”, dając działają w innym „wątku” aplikacji, dzięki czemu praca programu może zostać podzielona na wiele procesorów w nowoczesnym komputerze PC, podczas gdy interfejs użytkownika aplikacji pozostaje „responsywny” na żądania systemu operacyjnego dotyczące ponownego rysowania interfejsu użytkownika i wykonywania inne zadania wizualne. Pojęcie wątkowości nie jest trudne do zrozumienia, ale do czasu C # 4.0 zasadniczo wymagało podzielenia metody na dwie części; jedna metoda rozpoczyna operację asynchroniczną, a druga jest wywoływana, gdy wątek w tle zakończy pracę. Już nie; te dwa nowe słowa kluczowe pozwalają na zdefiniowanie funkcji wykonującej pracę asynchroniczną w bardzo synchroniczny sposób, podczas gdy kompilator rozdziela metody za kulisami podczas budowania kodu.

Odpowiedź

Nie ma formalnej definicji cukru syntaktycznego, jest to mgliste pojęcie.

Cukier syntaktyczny w swojej najbardziej akceptowanej definicji to dodatkowa składnia, która jest natychmiast tłumaczona przez kompilator na bardziej prymitywną i uciążliwą formę, ale pozwala programiście na „słodsze” doświadczenie w wyrażaniu pewnych typowych instrukcji.

Problem z tą definicją polega na tym, że „dodatkowa” składnia nie jest zbyt znaczącym opisem. W niektórych przypadkach jest całkiem jasne, że mamy cukier syntaktyczny, na przykład raport w języku Haskell wyraźnie definiuje pewne elementy składniowe (bloki do i listy składane) poprzez ich tłumaczenie w prostszej składni. Jest to dość wyraźny przypadek cukru składniowego, istnieją one tylko po to, aby ułatwić pisanie programu, a nie w żadnym głębokim sensie w tłumaczeniu programu przez kompilator na symboliczne drzewo.

W innych przypadkach, jest to o wiele mniej jasne, ponieważ język nie zawraca sobie głowy tego rodzaju formalizacją, na przykład dekoratory w Pythonie są często opisywane przez to, jak można napisać równoważny kod bez nich, ale o ile wiem, nigdy nie jest to wyraźnie powiedziane: „ty nie powinien kompilować dekoratorów bezpośrednio do reprezentacji pośredniej, ale raczej przetłumaczyć je wcześniej w ten sposób ”. Niektóre implementacje Pythona mogą to zrobić, ale inne mogą mieć dodane dekoratory jako funkcję ich pośredniej reprezentacji.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *