Co jest bezpieczne dla typu?

Odpowiedzi:

246

Bezpieczeństwo typu oznacza, że ​​kompilator sprawdzi typy podczas kompilacji i zgłosi błąd, jeśli spróbujesz przypisać zły typ do zmiennej.

Kilka prostych przykładów:

// Fails, Trying to put an integer in a string
String one = 1;
// Also fails.
int foo = "bar";

Dotyczy to również argumentów metod, ponieważ przekazujesz im typy jawne:

int AddTwoNumbers(int a, int b)
{
    return a + b;
}

Gdybym próbował to nazwać za pomocą:

int Sum = AddTwoNumbers(5, "5");

Kompilator zgłasza błąd, ponieważ przekazuję ciąg znaków („5”) i oczekuje on liczby całkowitej.

W luźno wpisanym języku, takim jak javascript, mogę wykonać następujące czynności:

function AddTwoNumbers(a, b)
{
    return a + b;
}

jeśli nazywam to tak:

Sum = AddTwoNumbers(5, "5");

JavaScript automatycznie konwertuje 5 na ciąg znaków i zwraca „55”. Wynika to z javascript używającego znaku + do konkatenacji łańcucha. Aby było to zgodne z typem, musisz zrobić coś takiego:

function AddTwoNumbers(a, b)
{
    return Number(a) + Number(b);
}

Lub ewentualnie:

function AddOnlyTwoNumbers(a, b)
{
    if (isNaN(a) || isNaN(b))
        return false;
    return Number(a) + Number(b);
}

jeśli nazywam to tak:

Sum = AddTwoNumbers(5, " dogs");

JavaScript automatycznie konwertuje 5 na ciąg i dołącza je, aby zwrócić „5 psów”.

Nie wszystkie języki dynamiczne są tak wybaczające jak javascript (w rzeczywistości język dynamiczny nie implikuje luźnego języka pisanego (patrz Python)), niektóre z nich faktycznie powodują błąd w czasie wykonywania podczas rzutowania typu nieprawidłowego.

Chociaż jest to wygodne, otwiera cię na wiele błędów, które można łatwo przeoczyć i które można zidentyfikować tylko poprzez przetestowanie uruchomionego programu. Osobiście wolę, aby mój kompilator powiedział mi, czy popełniłem ten błąd.

Teraz wróć do C # ...

C # obsługuje funkcję języka o nazwie kowariancja , co w zasadzie oznacza, że ​​można podstawić typ podstawowy na typ potomny i nie powodować błędów, na przykład:

 public class Foo : Bar
 {
 }

Tutaj stworzyłem nową klasę (Foo), która podklasuje Bar. Teraz mogę utworzyć metodę:

 void DoSomething(Bar myBar)

I nazwij to za pomocą Foo lub paska jako argumentu, oba będą działać bez powodowania błędu. Działa to, ponieważ C # wie, że każda klasa potomna Bar będzie implementować interfejs Bar.

Nie można jednak wykonać odwrotności:

void DoSomething(Foo myFoo)

W tej sytuacji nie mogę przekazać Bar do tej metody, ponieważ kompilator nie wie, że Bar implementuje interfejs Foo. Wynika to z faktu, że klasa potomna może (i zwykle będzie) znacznie różnić się od klasy macierzystej.

Oczywiście, teraz zszedłem daleko od głębokiego końca i wykroczyłem poza pierwotne pytanie, ale to wszystko dobrze wiedzieć :)

FlySwat
źródło
26
Wydaje mi się, że ta odpowiedź jest błędna: bezpieczeństwo typu niekoniecznie jest egzekwowane podczas kompilacji. Rozumiem, że na przykład Schemat jest uważany za bezpieczny typu, ale jest dynamicznie sprawdzany (bezpieczeństwo typu jest wymuszane w czasie wykonywania). Jest to głównie parafraza wstępu do typów i języków programowania autorstwa Benjamina C. Pierce'a.
Nicolas Rinaudo
11
To, co opisujesz, nazywa się polimorfizmem, a nie kowariancją. Kowariancja jest stosowana w lekach generycznych.
IllidanS4 chce powrotu Moniki
@NicolasRinaudo zauważa, że ​​luka między językami dynamicznymi a statycznymi jest zmniejszana przez dynamiczną kompilację i prekompilację dla języków „interpretowanych” oraz przez odbicie w językach „skompilowanych”. Refleksja pozwala na przykład wpisywać kaczki w czasie wykonywania, więc skompilowany język może powiedzieć „hej, to ma metodę Quack (), wywołam to i zobaczę, co się stanie”. Języki podobne do Pascala często mają (opcjonalne) sprawdzanie przepełnienia środowiska wykonawczego, co prowadzi do błędów „kompilatora” występujących w środowisku wykonawczym „nie można dopasować liczby całkowitej dostarczonej do 8-bitowego miejsca docelowego {zrzut pamięci}.
Kod Abominator
2
Twoje przykładowe odniesienia do pojęcia o nazwie „silnie typowane”, które nie jest tym samym co bezpieczeństwo typu. Bezpieczeństwo typów polega na tym, że język wykrywa błędy typu podczas wykonywania lub kompilacji. Na przykład Python jest słabo wpisany i bezpieczny. Ta odpowiedź powinna zostać oflagowana, ponieważ jest bardzo myląca.
dantebarba
wyjaśnienie w ogólności v. dobre, ale bezpieczeństwo typu nie jest takie samo jak silnie napisane
senseiwu
57

Bezpieczeństwo typów nie powinno być mylone z pisaniem statycznym / dynamicznym lub pisaniem mocnym / słabym.

Język bezpieczny dla typu to taki, w którym jedynymi operacjami, które można wykonać na danych, są te, które są akceptowane przez typ danych. Oznacza to, że jeśli dane są typu Xi Xnie obsługują operacji y, język nie pozwoli na wykonanie y(X).

Ta definicja nie określa reguł, kiedy jest ona zaznaczona. Może być w czasie kompilacji (pisanie statyczne) lub w czasie wykonywania (pisanie dynamiczne), zwykle za pośrednictwem wyjątków. Może być trochę jedno i drugie: niektóre języki o typie statycznym pozwalają na rzutowanie danych z jednego typu na inny, a ważność rzutowań musi być sprawdzana w czasie wykonywania (wyobraź sobie, że próbujesz rzutować Objectna Consumer- kompilator nie ma sposób na sprawdzenie, czy jest to dopuszczalne, czy nie).

Bezpieczeństwo tekstu niekoniecznie oznacza również silne pisanie na maszynie - niektóre języki są powszechnie słabo pisane, ale prawdopodobnie bezpieczne. Weźmy na przykład Javascript: jego system typów jest tak słaby, jak to tylko możliwe, ale wciąż ściśle określony. Umożliwia automatyczne rzutowanie danych (powiedzmy ciągów na int), ale w ramach ściśle określonych reguł. Według mojej wiedzy nie ma przypadku, w którym program JavaScript zachowałby się w nieokreślony sposób, a jeśli jesteś wystarczająco sprytny (nie jestem), powinieneś być w stanie przewidzieć, co się stanie podczas czytania kodu JavaScript.

Przykładem niebezpiecznego języka programowania jest C: odczyt / zapis wartości tablicy poza jej granicami ma niezdefiniowane zachowanie według specyfikacji . Nie da się przewidzieć, co się stanie. C jest językiem, który ma system typów, ale nie jest bezpieczny dla typów.

Nicolas Rinaudo
źródło
1
jakie są inne przykłady języków niebezpiecznych dla typu? Co rozumiesz przez „zapisywanie wartości tablicy poza jej granicami, zachowanie jest niezdefiniowane według specyfikacji. Nie można przewidzieć, co się stanie”. Podobnie jak JavaScript, zwróci niezdefiniowane, prawda? A tak naprawdę wszystko może się zdarzyć. Czy możesz podać tego przykład?
ARK,
1
@AkshayrajKore na pewno. Tablice są wskaźnikami pamięci, więc zapisując poza granicami, możesz nadpisywać dane innego programu - co nie może nic zrobić, spowodować awarię programu, spowodować wymazanie dysku twardego - jest niezdefiniowany i zależy od tego, kto czyta ten fragment pamięci i jak zareaguje na to.
Nicolas Rinaudo
@Nicolas Rinaudo To nie jest poprawne. Powinieneś przeczytać o pamięci wirtualnej. Każdy proces ma własną wirtualną przestrzeń adresową, więc proces nie może „nadpisać danych innego programu” w taki sposób.
ilstam
Masz rację - powinieneś przeczytać , że możesz nadpisywać inną część pamięci programu - aż do samego programu?
Nicolas Rinaudo,
@NicolasRinaudo Segment kodu programu jest odwzorowany tylko do odczytu w wirtualnej przestrzeni adresowej. Więc jeśli spróbujesz do niego napisać, spowoduje to błąd segmentacji i twój program się zawiesi. Tak samo, jeśli spróbujesz zapisać w niezmapowanej pamięci, co spowodowałoby błąd strony i ponowną awarię. Jeśli jednak nie masz szczęścia, możesz po prostu nadpisać dane ze stosu lub stosu procesu (jak inne zmienne lub inne rzeczy). W takim przypadku prawdopodobnie nie rozbiłbyś się natychmiast, co jest jeszcze gorsze, ponieważ nie zauważysz błędu do (miejmy nadzieję) później!
ilstam
32

Bezpieczeństwo to nie tylko rodzaj kompilacji ograniczenia czasowe, ale czas pracy ograniczenia. Wydaje mi się, że nawet po tak długim czasie możemy to jeszcze wyjaśnić.

Istnieją 2 główne kwestie związane z bezpieczeństwem typu. Pamięć ** i typ danych (z odpowiednimi operacjami).

Pamięć**

charTypowo wymaga 1 bajt na znak lub 8 bitów (w zależności od języka, Java i C # przechowywania znaków Unicode, które wymagają 16 bitów). int4 bajtów, lub 32 bitów (zazwyczaj).

Naocznie:

char: |-|-|-|-|-|-|-|-|

int : |-|-|-|-|-|-|-|-| |-|-|-|-|-|-|-|-| |-|-|-|-|-|-|-|-| |-|-|-|-|-|-|-|-|

Bezpieczny język typu nie pozwala na wstawienie int w char w czasie wykonywania (powinno to wyrzucić jakiś wyjątek klasy lub wyjątek braku pamięci). Jednak w niebezpiecznym języku typu nadpisujesz istniejące dane w kolejnych 3 sąsiednich bajtach pamięci.

int >> char:

|-|-|-|-|-|-|-|-| |?|?|?|?|?|?|?|?| |?|?|?|?|?|?|?|?| |?|?|?|?|?|?|?|?|

W powyższym przypadku 3 bajty po prawej stronie są nadpisywane, więc wszelkie wskaźniki tej pamięci (powiedzmy 3 kolejne znaki), które oczekują uzyskania przewidywalnej wartości char, będą teraz miały śmieci. Powoduje to undefinedzachowanie w twoim programie (lub gorzej, być może w innych programach, w zależności od sposobu przydzielania pamięci przez system operacyjny - w dzisiejszych czasach jest to bardzo mało prawdopodobne).

** Chociaż ten pierwszy problem nie dotyczy technicznego typu danych, wpisz bezpieczne języki, aby rozwiązać je nieodłącznie i wizualnie opisuje problem osobom nieświadomym, jak „alokacja pamięci” wygląda.

Typ danych

Bardziej subtelny i bezpośredni problem z typem występuje wtedy, gdy dwa typy danych używają tego samego przydziału pamięci. Weź int vs. niepodpisaną int. Oba mają 32 bity. (Równie łatwo może być char [4] i int, ale bardziej powszechnym problemem jest uint vs. int).

|-|-|-|-|-|-|-|-| |-|-|-|-|-|-|-|-| |-|-|-|-|-|-|-|-| |-|-|-|-|-|-|-|-|

|-|-|-|-|-|-|-|-| |-|-|-|-|-|-|-|-| |-|-|-|-|-|-|-|-| |-|-|-|-|-|-|-|-|

Niebezpieczny język typu pozwala programiście odwoływać się do prawidłowo przydzielonego zakresu 32 bitów, ale gdy wartość int bez znaku jest odczytywana w przestrzeni int (lub odwrotnie), znów mamy undefinedzachowanie. Wyobraź sobie problemy, jakie może to powodować w programie bankowym:

„Koleś! Przekroczyłem limit 30 $ i teraz mam 65 506 $ !!”

... ”, programy bankowe używają znacznie większych typów danych. ;) LOL!

Jak już zauważyli inni, kolejnym problemem są operacje obliczeniowe na typach. Zostało to już wystarczająco uwzględnione.

Szybkość a bezpieczeństwo

Większość programistów dzisiaj nigdy nie musi się martwić takimi rzeczami, chyba że używa czegoś takiego jak C lub C ++. Oba te języki pozwalają programistom łatwo naruszać bezpieczeństwo typu w czasie wykonywania (bezpośrednie odwoływanie do pamięci), pomimo najlepszych starań kompilatorów, aby zminimalizować ryzyko. JEDNAK to nie wszystko jest złe.

Jednym z powodów, dla których języki te są tak szybkie obliczeniowo, jest to, że nie są obciążone weryfikacją zgodności typów podczas operacji w czasie wykonywania, takich jak na przykład Java. Zakładają, że programista jest dobrym racjonalnym bytem, ​​który nie doda łańcucha i int razem, a za to programista jest nagradzany szybkością / wydajnością.

Gr3go
źródło
27

Wiele odpowiedzi tutaj łączy bezpieczeństwo typu z typowaniem statycznym i dynamicznym. Język dynamicznie typowany (jak smalltalk) może być również bezpieczny dla typu.

Krótka odpowiedź: język jest uznawany za bezpieczny dla typu, jeśli żadna operacja nie prowadzi do nieokreślonego zachowania. Wielu uważa wymóg jawnego typowania konwersji za niezbędny do ścisłego wpisania języka , ponieważ automatyczne konwersje mogą czasem prowadzić do dobrze określonych, ale nieoczekiwanych / nieintuicyjnych zachowań.

ididak
źródło
1
Czekaj, swoją definicję typu bezpieczeństwa nie ma ani jednego słowa „type”: D if no operation leads to undefined behavior.
VasiliNovikov
1
Nie zgadzałbym się również z taką definicją. Myślę, że bezpieczeństwo typu oznacza dokładnie 1. istnienie typów 2. znajomość ich dla kompilatora i oczywiście odpowiednie kontrole.
VasiliNovikov
10

Język programowania „bezpieczny dla typu” oznacza następujące rzeczy:

  1. Nie można odczytać z niezainicjowanych zmiennych
  2. Nie można indeksować tablic poza ich granice
  3. Nie można wykonywać rzutów typu niezaznaczonego
Kekule
źródło
8

Wyjaśnienie z wydziału sztuk wyzwolonych, a nie z wydziału nauk ścisłych:

Kiedy ludzie mówią, że język lub funkcja języka jest bezpieczna dla typu, oznacza to, że język pomoże ci na przykład przekazać coś, co nie jest liczbą całkowitą, do logiki, która oczekuje liczby całkowitej.

Na przykład w C # definiuję funkcję jako:

 void foo(int arg)

Kompilator powstrzyma mnie od zrobienia tego:

  // call foo
  foo("hello world")

W innych językach kompilator mnie nie zatrzyma (lub nie ma kompilatora ...), więc ciąg znaków zostanie przekazany do logiki i prawdopodobnie nastąpi coś złego.

Wpisz bezpieczne języki, spróbuj złapać więcej w „czasie kompilacji”.

Z drugiej strony, z bezpiecznymi językami typu, gdy masz ciąg taki jak „123” i chcesz operować nim jak int, musisz napisać więcej kodu, aby przekonwertować ciąg na int lub gdy masz int jak 123 i chcesz użyć go w komunikacie typu „Odpowiedź to 123”, musisz napisać więcej kodu, aby przekonwertować / rzutować na ciąg.

Corey Trager
źródło
4
Sztuk wyzwolonych głównym powiedziałby o wyjaśnienie :) Ty też pisanie utożsamiając statyczny i dynamiczny pisać.
ididak
1
Sztuki wyzwolone „kierunki”, a nie „kierunki”.
Corey Trager
5

Aby lepiej zrozumieć, obejrzyj poniższy film, który pokazuje kod w bezpiecznym języku (C #), a NIE w bezpiecznym języku (javascript).

http://www.youtube.com/watch?v=Rlw_njQhkxw

Teraz długi tekst.

Bezpieczeństwo typu oznacza zapobieganie błędom typu. Błąd typu występuje, gdy typ danych jednego typu jest przypisywany do innego typu NIEZNACZNIE i otrzymujemy niepożądane wyniki.

Na przykład JavaScript nie jest bezpiecznym językiem typu. W poniższym kodzie „num” jest zmienną numeryczną, a „str” jest łańcuchem. Javascript pozwala mi wykonywać „num + str”, teraz GUESS zrobi arytmetykę lub konkatenację.

Teraz dla poniższego kodu wyniki wynoszą „55”, ale ważnym punktem jest zamieszanie, które stworzyło, jaką operację wykona.

Dzieje się tak, ponieważ javascript nie jest bezpiecznym językiem. Pozwala to ustawić jeden typ danych na inny typ bez ograniczeń.

<script>
var num = 5; // numeric
var str = "5"; // string
var z = num + str; // arthimetic or concat ????
alert(z); // displays  “55”
</script>

C # jest językiem bezpiecznym dla typu. Nie pozwala na przypisanie jednego typu danych do innego typu danych. Poniższy kod nie pozwala operatorowi „+” na różnych typach danych.

wprowadź opis zdjęcia tutaj

Shivprasad Koirala
źródło
4

Bezpieczny typ oznacza, że ​​programowo typ danych dla zmiennej, wartości zwracanej lub argumentu musi spełniać określone kryteria.

W praktyce oznacza to, że 7 (typ liczby całkowitej) różni się od „7” (cytowany znak typu string).

PHP, JavaScript i inne dynamiczne języki skryptowe są zwykle słabo wpisane, ponieważ konwertują (ciąg) „7” na (liczbę całkowitą) 7, jeśli spróbujesz dodać „7” + 3, chociaż czasami musisz to zrobić jawnie (a Javascript używa znaku „+” do konkatenacji).

C / C ++ / Java tego nie zrozumie lub zamiast tego połączy wynik w „73”. Bezpieczeństwo typu zapobiega tego rodzaju błędom w kodzie, wyraźnie określając wymagania dotyczące typu.

Bezpieczeństwo typu jest bardzo przydatne. Rozwiązaniem powyższego „7” + 3 byłoby typ cast (int) „7” + 3 (równa się 10).

Jared Farrish
źródło
3

Pojęcie:

Aby być bardzo prostym Typ Bezpieczny jak znaczeń, upewnia się, że typ zmiennej powinien być bezpieczny

  1. żaden zły typ danych, np. nie może zapisać lub zainicjować zmiennej typu string z liczbą całkowitą
  2. Indeksy spoza zakresu nie są dostępne
  3. Zezwalaj tylko na określoną lokalizację pamięci

więc chodzi przede wszystkim o bezpieczeństwo typów pamięci w zakresie zmiennych.

azizsagi
źródło
2

Spróbuj tego wyjaśnienia na ...

TypeSafe oznacza, że ​​zmienne są sprawdzane statycznie pod kątem odpowiedniego przypisania w czasie kompilacji. Na przykład podaj łańcuch lub liczbę całkowitą. Te dwa różne typy danych nie mogą być przypisywane krzyżowo (tzn. Nie można przypisać liczby całkowitej do ciągu, ani nie można przypisać ciągu do liczby całkowitej).

W przypadku zachowania innego niż bezpieczny, rozważ to:

object x = 89;
int y;

jeśli spróbujesz to zrobić:

y = x;

kompilator zgłasza błąd, który mówi, że nie może przekonwertować System.Object na liczbę całkowitą. Musisz to zrobić jawnie. Jednym ze sposobów byłoby:

y = Convert.ToInt32( x );

Powyższe przypisanie nie jest bezpieczne. Przypisanie bezpiecznego typu to miejsce, w którym typy mogą być bezpośrednio przypisane do siebie.

W programie ASP.NET znajdują się kolekcje inne niż bezpieczne (np. Kolekcje aplikacji, sesji i stanu wyświetlania). Dobrą wiadomością o tych kolekcjach jest to, że (minimalizując kwestie związane z zarządzaniem wieloma serwerami) można umieścić praktycznie dowolny typ danych w dowolnym z trzech zbiorów. Zła wiadomość: ponieważ te kolekcje nie są bezpieczne dla typów, musisz odpowiednio rzucić wartości, gdy je odzyskasz.

Na przykład:

Session[ "x" ] = 34;

działa w porządku. Ale aby ponownie przypisać wartość całkowitą, musisz:

int i = Convert.ToInt32( Session[ "x" ] );

Przeczytaj o rodzajach, aby dowiedzieć się, w jaki sposób funkcja ta ułatwia wdrażanie bezpiecznych kolekcji.

C # to język bezpieczny dla typów, ale uważaj na artykuły o C # 4.0; pojawiają się ciekawe dynamiczne możliwości (czy to dobrze, że C # zasadniczo dostaje Option Strict: Off ... zobaczymy).

rp.
źródło
Osobiście nienawidzę Konwertuj. Aby zapisać, dlaczego po prostu nie używasz bezpiecznej obsady? Jest to tylko mniej funkcji wywołania na stosie wywołań.
FlySwat,
2

Type-Safe to kod, który uzyskuje dostęp tylko do miejsc w pamięci, do których ma dostęp, i tylko w dobrze określony, dozwolony sposób. Kod bezpieczny dla typu nie może wykonać operacji na obiekcie, który jest nieprawidłowy dla tego obiektu. Kompilatory języka C # i VB.NET zawsze generują kod typu, który jest sprawdzany pod kątem bezpieczeństwa typu podczas kompilacji JIT.

Jonuz
źródło
Masz na myśli bezpieczeństwo pamięci?
gołopot
1

Bezpieczeństwo typu oznacza, że ​​zestaw wartości, które można przypisać do zmiennej programu, musi spełniać dobrze zdefiniowane i testowalne kryteria. Zmienne bezpieczne dla typu prowadzą do bardziej niezawodnych programów, ponieważ algorytmy manipulujące zmiennymi mogą ufać, że zmienna pobierze tylko jeden z dobrze zdefiniowanego zestawu wartości. Utrzymanie tego zaufania zapewnia integralność i jakość danych i programu.

W przypadku wielu zmiennych zestaw wartości, które można przypisać do zmiennej, jest definiowany w momencie pisania programu. Na przykład zmienna o nazwie „kolor” może przyjmować wartości „czerwony”, „zielony” lub „niebieski” i nigdy żadnych innych wartości. W przypadku innych zmiennych kryteria te mogą ulec zmianie w czasie wykonywania. Na przykład zmienna o nazwie „kolor” może przyjmować wartości tylko w kolumnie „nazwa” tabeli „Kolory” w relacyjnej bazie danych, gdzie „czerwony”, „zielony” i „niebieski” to trzy wartości dla „nazwa” w tabeli „Kolory”, ale jakaś inna część programu komputerowego może być w stanie dodać do tej listy podczas działania programu, a zmienna może przyjmować nowe wartości po ich dodaniu do tabeli Kolory .

Wiele języków bezpiecznych dla typu daje złudzenie „bezpieczeństwa typu”, kładąc nacisk na ścisłe definiowanie typów dla zmiennych i pozwalając, aby zmiennej przypisywano tylko wartości tego samego „typu”. Z tym podejściem wiąże się kilka problemów. Na przykład program może mieć zmienną „yearOfBirth”, czyli rok, w którym dana osoba się urodziła, i kusi go, aby wpisać go jako krótką liczbę całkowitą. Nie jest to jednak liczba całkowita krótka. W tym roku jest to liczba mniejsza niż 2009 i większa niż -10000. Jednak ten zestaw rośnie o 1 każdego roku w miarę działania programu. Uczynienie tego „krótkim int” nie jest wystarczające. Aby ta zmienna była bezpieczna dla typu, potrzebna jest funkcja sprawdzania poprawności w czasie wykonywania, która zapewnia, że ​​liczba jest zawsze większa niż -10000 i mniejsza niż następny rok kalendarzowy.

Języki używające dynamicznego pisania (lub pisania kaczego lub manifestowania), takie jak Perl, Python, Ruby, SQLite i Lua, nie mają pojęcia zmiennych pisanych. Zmusza to programistę do napisania procedury sprawdzania poprawności w czasie wykonywania dla każdej zmiennej, aby upewnić się, że jest poprawna, lub znosić konsekwencje niewyjaśnionych wyjątków w czasie wykonywania. Z mojego doświadczenia wynika, że ​​programiści posługujący się statycznie typowanymi językami, takimi jak C, C ++, Java i C #, często są uśpieni myśleniem, że statycznie zdefiniowane typy są wszystkim, co muszą zrobić, aby uzyskać korzyści z bezpieczeństwa typu. Nie jest to po prostu prawdą w przypadku wielu przydatnych programów komputerowych i trudno jest przewidzieć, czy jest to prawdą w odniesieniu do jakiegokolwiek konkretnego programu komputerowego.

Długa i krótka .... Czy chcesz mieć bezpieczeństwo typu? Jeśli tak, to napisz funkcje czasu wykonywania, aby upewnić się, że zmiennej przypisuje się wartość, która jest zgodna z dobrze zdefiniowanymi kryteriami. Wadą jest to, że sprawia, że ​​analiza domen jest naprawdę trudna dla większości programów komputerowych, ponieważ musisz jawnie zdefiniować kryteria dla każdej zmiennej programu.

Jay Godse
źródło
2
Zmienne w języku Python są wpisywane ( w rzeczywistości są mocno wpisywane). Spróbuj to zrobić, na przykład: „str” + 1. Otrzymasz błąd. Jednak typy są sprawdzane w czasie wykonywania, a nie w czasie kompilacji.
mipadi