Widzę te terminy w różnych miejscach w programowaniu i mam niejasne pojęcie o ich znaczeniu. Wyszukiwanie pokazuje mi, że takie rzeczy były w rzeczywistości pytane o przepełnienie całego stosu. O ile mi wiadomo, pisanie statyczne / dynamiczne w językach subtelnie różni się od pisania silnego / słabego, ale jaka to różnica mi umyka. Różne źródła wydają się używać różnych znaczeń, a nawet terminów zamiennie. Nie mogę znaleźć czegoś, co mówi o obu tych rzeczach i właściwie wyjaśnia różnicę. Byłoby miło, gdyby ktoś mógł to jasno przeliterować tutaj dla mnie i reszty świata.
319
Odpowiedzi:
Wpisywanie statyczne / dynamiczne dotyczy momentu uzyskania informacji o typie (w czasie kompilacji lub w czasie wykonywania)
Silne / słabe pisanie dotyczy tego, jak ściśle rozróżniane są typy (np. Czy język próbuje dokonać niejawnej konwersji ciągów na liczby).
Zobacz stronę wiki, aby uzyskać bardziej szczegółowe informacje.
źródło
"12" + "34"
byłby równy"46"
, ale"12" + "34Q"
byłby równy"1234Q"
[na szczęście można by pisać,"12" & "34"
gdyby ktoś chciał łączyć]. Co ciekawe, zmienne zawierające liczby zapisywały je jako zmiennoprzecinkowe podwójnej precyzji, a matematyka na takich zmiennych używała wartości zmiennoprzecinkowych bez mungowania łańcucha, ale nie było sposobu, aby zapytać, czy zmienna jest łańcuchem czy liczbą.Odkryłeś słabość terminologii używanej przez amatorów do mówienia o językach programowania. Nie używaj terminów „mocne” i „słabe” pisanie , ponieważ nie mają one powszechnie uzgodnionego znaczenia technicznego. Natomiast wpisywanie statyczne oznacza, że programy są sprawdzane przed uruchomieniem, a program może zostać odrzucony przed jego uruchomieniem. Wpisywanie dynamiczne oznacza, że typy wartości są sprawdzane podczas wykonywania , a źle wpisana operacja może spowodować zatrzymanie programu lub inny sygnał błędu w czasie wykonywania . Podstawowym powodem pisania statycznego jest wykluczenie programów, które mogą mieć takie „błędy typu dynamicznego”.
Silne pisanie na ogół oznacza, że nie ma luk w systemie typów, natomiast słabe pisanie oznacza, że system typów może zostać obalony (unieważniając wszelkie gwarancje). Terminy są często używane nieprawidłowo, aby oznaczać pisanie statyczne i dynamiczne. Aby zobaczyć różnicę, pomyśl o C: język jest sprawdzany podczas kompilacji (pisanie statyczne), ale jest wiele luk; możesz rzucić dowolną wartość na inny typ tego samego rozmiaru - w szczególności możesz dowolnie rzutować typy wskaźników. Pascal był językiem, który miał być mocno napisany na maszynie, ale słynął z nieprzewidzianej luki: wariant zapisu bez tagu.
Implementacje silnie typowanych języków często nabierają luk w czasie, zwykle po to, aby część systemu wykonawczego mogła zostać zaimplementowana w języku wysokiego poziomu. Na przykład Objective Caml ma wywoływaną funkcję,
Obj.magic
która w czasie wykonywania po prostu zwraca swój argument, ale w czasie kompilacji konwertuje wartość dowolnego typu na dowolny inny typ. Moim ulubionym przykładem jest Modula-3, której projektanci nazwali konstrukcję rzutowąLOOPHOLE
.Powiedziawszy to, nie można liczyć na to, że dwie osoby będą używać słów „silny” i „słaby” w dokładnie taki sam sposób. Więc ich unikaj.
źródło
Mówiąc prosto: w języku o typie statycznym typ jest statyczny , co oznacza, że po ustawieniu zmiennej na typ NIE MOŻNA go 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:
Podczas gdy w języku dynamicznie typowanym typ jest dynamiczny , co oznacza, że po ustawieniu zmiennej na typ, MOŻNA ją zmienić. Wynika to z faktu, że pisanie jest powiązane z wartością, a nie ze zmienną.
Na przykład w Pythonie:
Z drugiej strony, silne / słabe pisanie w języku jest powiązane z niejawnymi konwersjami typów (częściowo zaczerpniętymi z odpowiedzi @ Dario):
Na przykład w Pythonie:
podczas gdy w PHP:
Wpisywanie statyczne pozwala sprawdzić poprawność typu w czasie kompilacji. Języki o typie statycznym są zwykle kompilowane, a języki o typie dynamicznym są interpretowane. Dlatego języki dynamicznie wpisywane mogą sprawdzać pisanie w czasie wykonywania.
źródło
Słabe pisanie oznacza, że typ obiektu może się zmieniać w zależności od kontekstu. Na przykład w słabo wpisanym języku ciąg „123” może być traktowany jako liczba 123, jeśli dodasz do niego kolejny numer. Przykładami języków o słabym pisaniu są bash, awk i PHP.
Innym rodzajem słabo wpisanego języka jest C, gdzie dane pod adresem pamięci można traktować jako inny typ przez rzutowanie.
W silnie typowanym języku typ obiektu nie zmienia się - int jest zawsze int i próba użycia go jako łańcucha spowoduje błąd. Zarówno Java, jak i Python są mocno wpisane.
Różnica między pisaniem dynamicznym a statycznym polega na egzekwowaniu reguł typów. W języku o typie statycznym typ każdej zmiennej i parametru musi być zadeklarowany w źródle i jest wymuszany w czasie kompilacji. W języku dynamicznie wpisywanym typy są sprawdzane tylko wtedy, gdy są używane w czasie wykonywania. Zatem Java jest wpisywana statycznie, a Python jest wpisywany dynamicznie.
Jednak granice mogą być czasami rozmyte. Na przykład, chociaż Java jest wpisywana statycznie, za każdym razem, gdy używasz refleksji lub rzutowania (np. Podczas używania kontenerów obiektów), odkładasz sprawdzanie typu na środowisko wykonawcze.
Podobnie najbardziej silnie wpisane języki będą nadal automatycznie konwertować między liczbami całkowitymi i liczbami zmiennoprzecinkowymi (aw niektórych językach BigInts z precyzją alfabetyczną).
źródło
f
przyjmuje argumentx
(fun f(x)
) [**, więc żadne typy nie są deklarowane **], a treść funkcji tox+1
. Bez zadeklarowanych typów kompilator zorientuje się, żex
musi to być int.- fun f x = x + 1;
val f = fn : int -> int
5 + 'c' // OK
Dzisiaj badając ten temat natknąłem się na ten świetny artykuł http://blogs.perl.org/users/ovid/2010/08/what-to-know-before-debating-type-systems.html To wyjaśniło wiele rzeczy dla mnie i pomyślałem, że może to dodać do niektórych świetnych odpowiedzi powyżej.
Mocne i słabe pisanie:
Typy statyczne i dynamiczne
Typy jawne / niejawne:
źródło
Ze Scott's Programming Language Pragmatics , wydanie trzecie, strona 291, mamy
W prostych słowach, pisanie statyczne / dynamiczne odnosi się do czasu, w którym następuje sprawdzenie typu: czas kompilacji dla pisania statycznego i czas wykonywania dla języków dynamicznych. Podobnie, silne / słabe pisanie odnosi się do tego, jak agresywny jest język w egzekwowaniu swojego systemu czcionek.
Próbowałem przetłumaczyć opis Scotta na ładny schemat, który zamieściłem poniżej.
źródło
Myślę, że inni koledzy zrobili dobrą robotę, esp. wyjaśniając różnicę między pisaniem statycznym a dynamicznym. Ale jeśli chodzi o mocne i słabe pisanie, należy powiedzieć, że istnieją różne interpretacje / poglądy.
Oto dwa przykłady:
Niektórzy twierdzą, że Haskell jest silnie napisany na maszynie, ponieważ nie wolno dokonywać żadnych konwersji typu.
Inni (np. Pogląd Dario) twierdzą, że język, który pozwala celowo konwertować ciąg znaków na liczbę, jest celowo słabo wpisany, ale nawet inni nazywają to po prostu pisaniem kaczych znaków.
Oba stwierdzenia podkreślają nie przeciwne skrajności systemu typów, ale zupełnie inne aspekty. Tak więc przyłączam się do poglądu pana Ramseya, aby nie używać terminów „silny” i „słaby” do rozróżnienia systemów typów.
źródło
Języki o typie dynamicznym v / s
Języki silnie v / s słabo wpisane
Dobre dalsze odczyty
źródło
Języki o typie statycznym zazwyczaj wymagają deklarowania typów zmiennych, które są następnie sprawdzane w czasie kompilacji w celu ograniczenia błędów. Słowo „statyczny” w „statycznie typowany” odnosi się do „statycznej analizy kodu”, która jest procesem sprawdzania kodu przed jego wykonaniem. Chociaż możliwe jest, aby język o typie statycznym mógł wywnioskować typ zmiennej z prawej strony wyrażenia lub rzeczywistych parametrów, w praktyce większość języków o typie statycznym wymaga jawnego zadeklarowania typów zmiennych.
Języki o typie dynamicznym generalnie nie wymagają deklaracji zmiennych, aby mieć typy, i wnioskują o typach zmiennych na podstawie typu obliczonego w wyniku oceny prawej strony każdej instrukcji przypisania lub rzeczywistych parametrów wywołania funkcji. Ponieważ zmienna może mieć wiele przypisań przez cały okres jej istnienia, jej typ może zmieniać się w czasie i dlatego nazywany jest „typowaniem dynamicznym”. Ponadto środowisko wykonawcze musi śledzić bieżący typ dla każdej zmiennej, więc typ jest powiązany z wartością, a nie z deklaracją zmiennej. Można to uznać za system informacji o środowisku wykonawczym (RTTI).
Elementy języków pisanych statycznie i dynamicznie można łączyć. Na przykład C # obsługuje zarówno zmienne o typie statycznym, jak i dynamicznym, a języki zorientowane obiektowo ogólnie obsługują hierarchię typów. Języki o typie statycznym zazwyczaj zapewniają różne sposoby na ominięcie sprawdzania typu, na przykład za pomocą rzutowania, odbicia i dynamicznego wywoływania.
Mocne vs. słabe pisanie odnosi się do kontinuum tego, jak bardzo język próbuje zapobiec błędom z powodu używania zmiennej tak, jakby był jednym typem, podczas gdy w rzeczywistości jest innym typem. Na przykład zarówno C, jak i Java są językami o typie statycznym, jednak Java korzysta ze znacznie silniejszego sprawdzania typów niż C. Poniższy kod C z przyjemnością się kompiluje i uruchamia, i wstawi losową wartość do zmiennej b w czasie wykonywania, najprawdopodobniej powodując pluskwa:
Odpowiednik kodu Java spowoduje błąd kompilacji, co jest ogólnie preferowane:
źródło