Dużo słyszę, że nowe języki programowania są dynamicznie wpisywane, ale co to właściwie oznacza, gdy mówimy, że język jest dynamicznie pisany a nie statyczny?
945
Dużo słyszę, że nowe języki programowania są dynamicznie wpisywane, ale co to właściwie oznacza, gdy mówimy, że język jest dynamicznie pisany a nie statyczny?
Odpowiedzi:
Języki wpisywane statycznie
Język jest wpisywany statycznie, jeśli typ zmiennej jest znany w czasie kompilacji. W przypadku niektórych języków oznacza to, że jako programista musisz określić, jakiego typu jest każda zmienna (np .: Java, C, C ++); inne języki oferują pewną formę wnioskowania o typie , zdolność systemu typów do wywnioskowania typu zmiennej (np .: OCaml, Haskell, Scala, Kotlin)
Główną zaletą jest to, że kompilator może wykonywać wszelkiego rodzaju sprawdzanie, a zatem wiele trywialnych błędów jest wykrywanych na bardzo wczesnym etapie.
Przykłady: C, C ++, Java, Rust, Go, Scala
Języki wpisywane dynamicznie
Język jest dynamicznie wpisywany, jeśli ten typ jest powiązany z wartościami w czasie wykonywania, a nie nazwanymi zmiennymi / polami / itp. Oznacza to, że jako programista możesz pisać trochę szybciej, ponieważ nie musisz za każdym razem określać typów (chyba że używasz języka o typie statycznym z wnioskowaniem typu ).
Przykłady: Perl, Ruby, Python, PHP, JavaScript
Większość języków skryptowych ma tę funkcję, ponieważ i tak nie ma kompilatora do statycznego sprawdzania typu, ale może się zdarzyć, że szukasz błędu wynikającego z błędnej interpretacji typu zmiennej przez interpreter. Na szczęście skrypty są zwykle małe, więc błędy nie mają tak wielu miejsc do ukrycia.
Większość języków z dynamicznym pisaniem pozwala na podanie informacji o typie, ale nie wymaga ich. Jeden z rozwijanych obecnie języków, Rascal , stosuje podejście hybrydowe, umożliwiając dynamiczne pisanie w obrębie funkcji, ale wymuszając pisanie statyczne dla podpisu funkcji.
źródło
Statycznie typowane języki programowania sprawdzają typy (tj. Proces weryfikacji i egzekwowania ograniczeń typów) w czasie kompilacji, w przeciwieństwie do czasu wykonywania .
Dynamicznie wpisywane języki programowania sprawdzają typ w czasie wykonywania, w przeciwieństwie do czasu kompilacji .
Przykłady języków o typie statycznym to: - Java, C, C ++
Przykłady dynamicznie wpisywanych języków to: - Perl, Ruby, Python, PHP, JavaScript
źródło
Oto przykład kontrastujący z tym, jak Python (dynamicznie wpisany) i Go (statycznie wpisany) obsługuje błąd typu:
Python sprawdza typ w czasie wykonywania, a zatem:
Działa idealnie dobrze i zapewnia oczekiwaną wydajność
Hi
. Błąd pojawia się tylko wtedy, gdy trafi się problematyczna linia:Produkuje
ponieważ odpowiednia linia została faktycznie wykonana.
Z drugiej strony sprawdzanie typu w czasie kompilacji:
Powyższe nie zostanie skompilowane z następującym błędem:
źródło
runhaskell
na przykład za pomocą.Mówiąc prosto: w języku o typie statycznym typy zmiennych są statyczne , co oznacza, że po ustawieniu zmiennej na typ nie można jej zmienić. Wynika to z faktu, że pisanie jest powiązane ze zmienną, a nie z wartością, do której się odnosi.
Na przykład w Javie:
Gdzie z drugiej strony: w dynamicznie typowanym języku typy zmiennych są dynamiczne , co oznacza, że po ustawieniu zmiennej na typ, MOŻNA ją zmienić. Wynika to z faktu, że pisanie jest powiązane z wartością, którą przyjmuje, a nie z samą zmienną.
Na przykład w Pythonie:
Dlatego najlepiej jest myśleć o zmiennych w dynamicznie wpisywanych językach jako o ogólnych wskaźnikach do wpisywanych wartości.
Podsumowując, wpisz opis (lub powinien był opisać) zmienne w języku, a nie w samym języku. Mogłoby to być lepiej wykorzystane jako język ze zmiennymi o typie statycznym w porównaniu do języka o zmiennych o typie dynamicznym IMHO.
Języki o typie statycznym są ogólnie językami kompilowanymi, dlatego kompilatory sprawdzają typy (czy to ma sens, prawda, ponieważ typów nie można później zmieniać w czasie wykonywania).
Języki o typie dynamicznym są na ogół interpretowane, dlatego sprawdzanie typu (jeśli istnieje) odbywa się w czasie wykonywania, gdy są używane. To oczywiście wiąże się z pewnym kosztem wydajności i jest jednym z powodów, dla których języki dynamiczne (np. Python, ruby, php) nie skalują się tak dobrze, jak te pisane na maszynie (java, c # itp.). Z innej perspektywy, języki o typie statycznym wiążą się z większymi kosztami początkowymi: sprawiają, że zwykle piszesz więcej kodu, trudniejszy kod. Ale to się później opłaca.
Dobrą rzeczą jest to, że obie strony pożyczają cechy z drugiej strony. Języki pisane zawierają bardziej dynamiczne funkcje, np. Generyczne i biblioteki dynamiczne w języku C #, a języki dynamiczne obejmują więcej sprawdzania typów, np. Adnotacje typów w pythonie lub wariant HACK PHP, które zwykle nie są rdzeniem języka i można je stosować żądanie.
Jeśli chodzi o wybór technologii, żadna ze stron nie ma wewnętrznej przewagi nad drugą. To tylko kwestia preferencji, czy chcesz na początku mieć większą kontrolę, czy elastyczność. po prostu wybierz odpowiednie narzędzie do pracy i sprawdź, co jest dostępne przeciwnie, przed rozważeniem zmiany.
źródło
http://en.wikipedia.org/wiki/Type_system
źródło
myObject[remoteDataName]
. : Wtedy nie ma sposobu, aby dowiedzieć się, którą właściwość wybierze, a nawet czy w ogóle jest to ważna właściwość.Terminologia „dynamicznie wpisywana” jest niestety myląca. Wszystkie języki są typowane statycznie, a typy są właściwościami wyrażeń (a nie wartości, jak niektórzy sądzą). Jednak niektóre języki mają tylko jeden typ. Są to tak zwane języki jednoznaczne. Jednym z przykładów takiego języka jest niepisany rachunek lambda.
W niepisanym rachunku lambda wszystkie terminy są terminami lambda, a jedyną operacją, którą można wykonać dla danego terminu, jest zastosowanie go do innego terminu. Dlatego wszystkie operacje zawsze prowadzą do nieskończonej rekurencji lub do wyrażenia lambda, ale nigdy nie sygnalizują błędu.
Jednakże, byliśmy w celu wzmocnienia bez typu rachunku lambda z pierwotnych liczb i operacji arytmetycznych, to może wykonywać operacje nonsensownych takie dodanie dwóch warunków lambda
(λx.x) + (λy.y)
. Można argumentować, że jedyną rozsądną rzeczą jest zasygnalizowanie błędu, gdy tak się stanie, ale aby móc to zrobić, każdą wartość należy oznaczyć wskaźnikiem wskazującym, czy jest to termin lambda czy liczba. Operator dodawania sprawdzi następnie, czy rzeczywiście oba argumenty są oznaczone liczbami, a jeśli nie są, zasygnalizuje błąd. Pamiętaj, że te tagi nie są typami, ponieważ typy są właściwościami programów, a nie wartości wytwarzanych przez te programy.Język, który to robi, jest nazywany typowaniem dynamicznym.
Wszystkie języki, takie jak JavaScript, Python i Ruby, są jednoznaczne. Znów
typeof
operator w JavaScript itype
funkcja w Pythonie mają mylące nazwy; zwracają tagi związane z operandami, a nie ich typy. Podobniedynamic_cast
w C ++ iinstanceof
Java nie sprawdzaj typów.źródło
Kompilacja kontra interpretacja
„Po przetłumaczeniu kodu źródłowego”
Pisanie na maszynie
„Po sprawdzeniu typów”
5 + '3'
jest przykładem błędu typu w silnie typowanych językach, takich jak Go i Python, ponieważ nie pozwalają one na „przymus typu” -> możliwość zmiany wartości w pewnych kontekstach, takich jak łączenie dwóch typów. Słabo wpisane języki, takie jak JavaScript, nie zgłaszają błędu pisowni (powoduje w'53'
).Definicje „statyczne i skompilowane” oraz „dynamiczne i zinterpretowane” są dość podobne ... ale pamiętaj, że to „gdy typy są sprawdzane” vs. „kiedy kod źródłowy jest tłumaczony”.
Otrzymasz ten sam błąd typu, niezależnie od tego, czy język jest skompilowany czy zinterpretowany ! Musisz oddzielić te warunki koncepcyjnie.
Przykład Pythona
Dynamiczny, zinterpretowany
Ponieważ Python jest interpretowany i dynamicznie wpisywany, tłumaczy tylko i sprawdza kod, na którym jest wykonywany.
else
Blok nie realizuje, więc5 + '3'
się nawet nie spojrzał!Co jeśli został wpisany statycznie?
Błąd typu zostałby zgłoszony przed uruchomieniem kodu. Nadal wykonuje sprawdzenie typu przed uruchomieniem, nawet jeśli jest interpretowane.
Co jeśli zostałby skompilowany?
else
Blok byłyby tłumaczone / spojrzał przed okresie czasu, ale ponieważ jest dynamicznie wpisany nie byłoby wyrzucić błąd! Dynamicznie wpisywane języki nie sprawdzają typów aż do wykonania, a linia ta nigdy się nie wykonuje.Idź Przykład
Statyczne, skompilowane
Typy są sprawdzane przed uruchomieniem (statyczne), a błąd typu jest natychmiast wychwytywany! Typy będą nadal sprawdzane przed uruchomieniem, jeśli zostaną zinterpretowane z takim samym wynikiem. Gdyby był dynamiczny, nie generowałby żadnych błędów, nawet jeśli kod byłby sprawdzany podczas kompilacji.
Wydajność
Skompilowany język będzie miał lepszą wydajność w czasie wykonywania, jeśli zostanie wpisany statycznie (w porównaniu z dynamicznym); znajomość typów pozwala na optymalizację kodu maszynowego.
Języki o typie statycznym mają lepszą wydajność w czasie wykonywania wewnętrznie, ponieważ nie trzeba dynamicznie sprawdzać typów podczas wykonywania (sprawdza przed uruchomieniem).
Podobnie, skompilowane języki są szybsze w czasie wykonywania, ponieważ kod został już przetłumaczony, zamiast konieczności „interpretowania” / tłumaczenia w locie.
Pamiętaj, że zarówno skompilowane, jak i statycznie wpisane języki będą miały opóźnienie przed uruchomieniem odpowiednio dla tłumaczenia i sprawdzania typu.
Więcej różnic
Wpisywanie statyczne wykrywa błędy wcześnie, zamiast znajdować je podczas wykonywania (szczególnie przydatne w przypadku długich programów). Jest bardziej „ścisły”, ponieważ nie pozwala na błędy nigdzie w twoim programie i często zapobiega zmianie typów zmiennych, co dodatkowo chroni przed niezamierzonymi błędami.
Pisanie dynamiczne jest bardziej elastyczne, co niektórzy doceniają. Zwykle pozwala zmiennym zmieniać typy, co może powodować nieoczekiwane błędy.
źródło
Języki o typie statycznym : każda zmienna i wyrażenie jest już znane w czasie kompilacji.
(
int a;
a może przyjmować tylko wartości typu całkowitego w czasie wykonywania)Przykłady: C, C ++, Java
Języki o typie dynamicznym : zmienne mogą przyjmować różne wartości w czasie wykonywania, a ich typ jest definiowany w czasie wykonywania.
(
var a;
a może przyjmować dowolne wartości w czasie wykonywania)Przykłady: Ruby, Python.
źródło
Sprawdzanie typów języków wpisywanych statycznie w czasie kompilacji, a typ NIE może ulec zmianie. (Nie przejmuj się komentarzami do rzutowania, tworzona jest nowa zmienna / odwołanie).
Dynamiczne sprawdzanie typów języków w czasie wykonywania, a typ zmiennej MOŻE być zmieniany w czasie wykonywania.
źródło
Słodkie i proste definicje, ale dopasowane do potrzeb: Języki o typie statycznym wiążą typ ze zmienną dla całego jego zakresu (Seg: SCALA) Języki o typie dynamicznym wiążą typ z rzeczywistą wartością, do której odwołuje się zmienna.
źródło
źródło
Języki o typie statycznym, takie jak C ++, Java i języki o typie dynamicznym, takie jak Python, różnią się tylko pod względem wykonania typu zmiennej. Języki o typie statycznym mają statyczny typ danych dla zmiennej, tutaj typ danych jest sprawdzany podczas kompilacji, więc debugowanie jest znacznie prostsze ... podczas gdy typowanie dynamiczne języki o nie robią tego samego, sprawdzany jest typ danych, który wykonuje program, a zatem debugowanie jest trochę trudne.
Co więcej, mają one bardzo małą różnicę i mogą być powiązane z językami silnie i słabo typowanymi . Język o silnym typie nie pozwala na użycie jednego typu jako drugiego np. C i C ++ ... podczas gdy słabo wpisane języki pozwalają np. Na phython
źródło
Wpisany statycznie
Typy są sprawdzane przed uruchomieniem, więc błędy mogą zostać wykryte wcześniej.
Przykłady = c ++
Dynamicznie wpisane
Typy są sprawdzane podczas wykonywania.
Przykłady = Python
źródło
Języki o typie statycznym (kompilator rozwiązuje wywołania metod i odwołania do kompilacji):
Dynamiczne języki pisane (decyzje podejmowane podczas działania programu):
źródło
dynamicznie typowany język pomaga szybko prototypować koncepcje algorytmów bez konieczności zastanawiania się, jakie typy zmiennych należy zastosować (co jest koniecznością statycznie typowanym języku e).
źródło
Pisanie statyczne: Języki, takie jak Java i Scala, są pisane statycznie.
Zmienne muszą zostać zdefiniowane i zainicjowane, zanim zostaną użyte w kodzie.
na przykład int x; x = 10;
System.out.println (x);
Pisanie dynamiczne: Perl jest językiem pisanym dynamicznie.
Zmienne nie muszą być inicjowane, zanim zostaną użyte w kodzie.
y = 10; użyj tej zmiennej w dalszej części kodu
źródło
$
), array (@
) i hash (%
). Typ zmiennej w Perlu jest znany w czasie kompilacji i pozostaje taki sam przez resztę życia zmiennych.