Więc piszemy:
Customer c = new Customer();
Dlaczego projekt nie jest taki, że piszemy:
c = new Customer();
c.CreditLimit = 1000;
Kompilator może obliczyć c punktów dla klienta i pozwolić na wywoływanie członków klienta na c?
Wiem, że możemy chcieć napisać:
IPerson c = new Customer();
IPerson e = new Employee();
aby móc pisać:
public string GetName(IPerson object)
{
return object.Name
}
string name = GetName(c); // or GetName(e);
Ale gdybyśmy napisali:
c = new Customer();
e = new Employee();
nadal możemy napisać:
public string GetName(object)
{
return object.Name
}
string name = GetName(c); // or GetName(e);
Kompilator może narzekać na kod bezpośrednio powyżej, jeśli typ odwołania do obiektu c nie obsługuje właściwości Name (ponieważ może sprawdzić, które elementy są używane w argumencie / parametrze w metodzie), lub środowisko wykonawcze może narzekać.
Nawet w przypadku dynamicznego słowa kluczowego C # nadal używamy zmiennej „typ” (określonej w czasie wykonywania). Ale dlaczego zmienna w ogóle potrzebuje typu? Jestem pewien, że musi być dobry powód, ale nie mogę o tym myśleć!
var
w języku C # i bycie obeznanym z tym, gdzie chcesz zadeklarować zmienną, jest zawsze dobre.Odpowiedzi:
źródło
a = new Bar()
a następnie wywołujesz metodę z klasyBaz
), kompilator zgłasza błąd. Języki, takie jak Haskell i OCaml, były pionierami wnioskowania o typie, ale występuje w języku C # za pomocąvar
słowa kluczowego.Masz doskonale uzasadniony punkt, istnieją języki, które nie śledzą typu zmiennej, i są nazywane „typami dynamicznymi”. Kategoria obejmuje języki takie jak JavaScript, Perl, Lisp i Python.
Zaletą, którą uzyskujemy ze statycznie typowanego języka, jest dodatkowe sprawdzanie błędów podczas kompilacji.
Załóżmy na przykład, że masz następującą metodę:
Byłoby możliwe, jeśli masz w kodzie klienta
bob
i pracownikajames
, przez pomyłkę zadzwonićaddCustomerContact(james, bob)
, co jest nieważne. Ale jeśli kompilator nie zna typów zmiennych, nie może ostrzec, że wykonałeś niepoprawne wywołanie, zamiast tego pojawia się błąd w czasie wykonywania ... a ponieważ języki z dynamicznym typowaniem nie sprawdzają typ parametrów przekazywanych do metod, problem ten występuje za każdym razem, gdy kod próbuje użyć właściwościjames
obiektu tylko dla klienta lub właściwości obiektu tylko dla pracownikabob
. Może to potrwać długo po dodaniu pary (James, Bob) do listy kontaktów klientów.Teraz można się zastanawiać, dlaczego nie można kompilator nadal wywnioskować typ
james
ibob
, i nadal nas ostrzec? Może to czasami być możliwe, ale jeśli zmienne naprawdę nie mają żadnego typu, moglibyśmy wykonać następujące czynności:Przypisywanie dowolnej wartości do dowolnej zmiennej jest całkowicie legalne, ponieważ powiedzieliśmy, że zmienne nie mają typu. Oznacza to również, że nie zawsze możemy znać typ zmiennej, ponieważ może ona być różnego typu w zależności od różnych ścieżek wykonania.
Ogólnie rzecz biorąc, języki pisane dynamicznie są używane w językach skryptowych, w których nie ma kroku kompilacji, a więc błędy kompilacji nie istnieją, co oznacza, że dodatkowe naciśnięcia klawiszy potrzebne do podania typu zmiennych nie byłyby bardzo przydatne.
Istnieją również wyraźne zalety dynamicznie pisanych języków, głównie w związku z tym, że do implementacji tego samego projektu potrzeba mniej kodu: interfejsy nie muszą być pisane, ponieważ wszystko jest „wypaczane” (dbamy tylko o to, jakie metody / właściwości ma obiekt , nie do jakiej klasy należy obiekt), zmienne nie muszą mieć jawnego typu ... z kompromisem, który dowiadujemy się o nieco mniejszej liczbie błędów, zanim zaczniemy uruchamiać nasz kod.
źródło
Dlatego profesjonalni programiści nie muszą się zastanawiać, czy
Co to jest błąd, w czasie kompilacji z językiem o typie statycznym lub w czasie wykonywania z językiem o typie dynamicznym. W każdym razie rozsądne.
źródło
Zakładając, że masz zmienną
one
(ustawioną na 1) i próbujesz ocenićone + one
. Jeśli nie masz pojęcia o typie, 1 + 1 będzie dwuznaczny. Możesz argumentować, że 2 lub 11 mogą być poprawnymi odpowiedziami. Staje się dwuznaczny, jeśli nie podano kontekstu.Widziałem to się zdarzyć w SQLite gdy typy baz danych zostały przypadkowo ustawiony
VARCHAR
zamiastINT
i gdy operacje zostały wykonane ludzie coraz nieoczekiwane rezultaty.W c # jeśli kontekst podaje typ, możesz użyć
var
słowa kluczowego.W czasie kompilacji skompiluje c oraz ez wywnioskowanymi typami.
źródło
1 + 1
zawsze ma typint
, ale nie trzeba go deklarować. Pytanie dotyczy tego, dlaczego zmienne mają typ, a nie wartości .variables
nie widzieć,values
kiedy użyłem1 + 1
w moim przykładzie. Chyba nie było jasne.one=1; print(one+one)
drukuje2
.one="1"; print(one+one)
odciski11
. Przykład SQLite jest bardziej przekonujący, ale problem polega na słabym pisaniu, więc nie jest tak naprawdę istotny dla C #.ORDER BY
nieumyślnym wykonaniem naVARCHAR
polu. Zobacz stackoverflow.com/questions/9103313/… .Zmienna nie musi mieć powiązanego typu. Języki, w których jest to prawdą, obejmują Lisp, Scheme, Erlang, Prolog, Smalltalk, Perl, Python, Ruby i inne.
Możliwe jest również, że zmienna ma typ, ale może nie trzeba pisać tego typu w programie. Nazywa się to zwykle wnioskowaniem typu. ML, Haskell i ich potomkowie mają potężne wnioskowanie o typach; niektóre inne języki mają go w mniejszych formach, na przykład
auto
deklaracje C ++ .Głównym argumentem przeciwko wnioskowaniu typu jest to, że szkodzi ono czytelności. Zazwyczaj łatwiej jest zrozumieć kod, gdy typy są zapisywane.
źródło
Kiedy identyfikujesz typ reprezentowany przez twoją zmienną, wypowiadasz się na temat kilku rzeczy. Identyfikujesz wymagania dotyczące alokacji pamięci dla zmiennej i definiujesz zasady zgodności i zasięgu dla zmiennej. Zapewnia to sposób na uniknięcie nieporozumień co do twoich zamiarów dotyczących przechowywanych danych oraz zapewnia stosunkowo tani sposób identyfikacji potencjalnych problemów w kodzie w czasie kompilacji.
Jeśli zadeklarujesz następujące zmienne:
Co możesz wnioskować na temat tych zmiennych? Czy jest
myVar
podpisany czy niepodpisany? Czy to 8-bit, 64-bit, czy coś pomiędzy? CzymyOtherVar
String (faktycznie tablica) czy Char? Czy to ANSI czy Unicode?Dostarczając określone typy danych, dostarczasz kompilatorowi wskazówek, w jaki sposób może zoptymalizować wymagania dotyczące pamięci dla twojej aplikacji. Niektóre języki nie przejmują się zbytnio tego rodzaju rzeczami, pozwalając na załatwienie tych spraw w czasie wykonywania, podczas gdy inne języki pozwalają na pewną liczbę dynamicznego pisania, ponieważ analizując kod, można wywnioskować typy danych.
Inną kwestią w przypadku silnie typowanych języków jest to, że oszczędza to konieczności podawania instrukcji do kompilatora za każdym razem, gdy używasz zmiennej. Czy potrafisz sobie wyobrazić, jak okropny i nieczytelny stałby się Twój kod, gdyby za każdym razem, gdy uzyskiwałeś dostęp do zmiennej, byłeś zmuszony skutecznie ją rzucić, aby poinformować kompilator, jaką to wartość? !!
źródło
Program komputerowy to wykres węzłów procesu opisujący, co powinna zrobić „maszyna” reprezentowana przez środowisko uruchomieniowe języka (w większości przypadków wyposażone w zestawy narzędzi), w jakiej kolejności lub w jakich warunkach. Ten wykres jest reprezentowany przez plik tekstowy (lub kilka plików tekstowych) napisany w określonym języku i (częściowo lub w całości) utworzony, gdy kompilator / tłumacz interpretuje (deserializuje) ten plik. Istnieją również środowiska (UML lub narzędzia do generowania programów graficznych), w których można zbudować ten wykres i wygenerować kod źródłowy w języku docelowym.
Dlaczego to mówię? Ponieważ prowadzi to do odpowiedzi na twoje pytanie.
Tekst programu zawiera wskazówki dotyczące tego, jak komputer powinien rozwiązać rzeczywiste zadanie, zawierający zarówno etapy procesu (warunki, działania) ORAZ strukturę (jakich komponentów używasz w rozwiązaniu). Ten ostatni oznacza, że dostajesz lub tworzysz niektóre wystąpienia innych komponentów, umieszczasz je w nazwanych polach (zmiennych) i używasz ich: dostęp do ich danych i usług.
Niektóre języki dają jednolite pudełka, w których ważna jest tylko etykieta, ale możesz w nich umieścić tylko wszystko, możesz nawet użyć zmiennej o nazwie „cel”, aby zapisać „Osobę” na początku, a „Samochód” na końcu ten sam algorytm. Inne wymagają stworzenia „ukształtowanych” pudełek, a więc różnych dla Osoby lub Samochodu - chociaż nadal pozwalają ci stworzyć „ogólne pudełko” (Java Object, C / C ++ void *, Objective C „id” ...) i rzuć to, jak chcesz. Wpisane języki pozwalają wyrazić strukturę w bardziej szczegółowy sposób, tworząc „kontrakty typu” dla zmiennych (chociaż można włamać się do tego ograniczenia), podczas gdy w językach niewypowiedzianych obsługiwane jest to podejście „Z pewnością będę wiedział, co włożyłem w to pole tym razem” jako domyślne i jedyne zachowanie.
Oba podejścia są realne, mają inteligencję kompilatora, wiele książek programistycznych, praktyk i ram napisanych przy użyciu ich (i innych ton książek o tych ramach) na różnych poziomach. Więc dzisiaj odpowiedź wydaje się być bardziej kwestią gustu i wiedzy rzeczywistego zespołu programistów niż właściwie uzasadnionym, zmierzonym i zweryfikowanym stwierdzeniem, czy używać typów, czy nie.
Myślę, że nie trzeba mówić, że wolę zasady od trików, zwłaszcza w przypadku długoterminowych projektów dużego zespołu (aka: „poważnych”). Powód: o ile wiem, najbardziej prawdopodobnymi przyczynami niepowodzenia / poślizgu projektu SW są: niejasne wymagania i kiepski projekt (80%! Z badań, które znam), i tylko kilka procent pozostaje do faktycznego kodowania. Wszystkie zasady i umowy wymuszają czystsze projektowanie, myślenie naprzód i wymagają, aby decyzje były podejmowane wcześniej i przez właściwe osoby. Rodzaje oznaczają zasady: mniej „swobody” i „chłodu” - więcej przygotowania, myślenia, kodowania standardów, kontrolowanej pracy zespołowej. Dla mnie brzmi to jak czynnik sukcesu, a także „dom, słodki dom”.
Moje 2 centy.
źródło
AFIAK wszystkie języki z dynamicznym pisaniem są tłumaczonymi językami. To już jest bardzo nieefektywne, dodanie nieefektywności pisania dynamicznego nie będzie dużą stratą czasu. Jednak skompilowany język nie będzie tak naprawdę odnosił się do rzeczy po nazwie, gdy jest uruchomiony. (Z wyjątkiem sporadycznego użycia odbicia .net lub podobnych - cech, które są bardzo powolne w porównaniu do języka bazowego.) Wyszukiwanie wszystkich tych nazw będzie powolne, powolne, powolne.
źródło
Języki o typie dynamicznym są często reklamowane jako „obiektowe”. Oni nie są. Mogą być zorientowane na enkapsulację, ale nigdy zorientowane obiektowo. Orientacja obiektowa dotyczy przede wszystkim typów.
„Chłopiec jedzie rowerem brata do sklepu spożywczego i kupuje od sklepikarza bochenek chleba”. Używając orientacji obiektowej, można od razu napisać zestaw klas (typów), aby opisać ten rzeczywisty scenariusz.
W języku z dynamicznym pisaniem scenariusz mógł być reprezentowany tylko w następujący sposób:
„Obiekt przesuwa obiekt swojego obiektu na obiekt i kupuje obiekt od obiektu”.
Moc orientacji obiektowej polega na tym, że jest w stanie modelować świat w sposób naturalny, dzięki czemu twórca oprogramowania może korzystać z obu stron mózgu do pisania oprogramowania i rozwiązywać problemy bardziej jako człowiek, a nie jako programista. Ta moc jest nieobecna w dynamicznie pisanych językach.
Pisanie statyczne pozwala na lepszą wydajność kodowania, możliwość ponownego użycia i konserwacji, ponieważ zintegrowane środowiska programistyczne znają typy zmiennych. Znając typy zmiennych, IDE może zapewnić automatyczne uzupełnianie, dzięki czemu programiści nie muszą odwoływać się do definicji klasy w celu zapamiętania, czy właściwość elementu została przeliterowana „backlightControl”, „backLightControl” lub „bkLightCtrl”.
Wpisywanie statyczne pozwala na automatyczne refaktoryzowanie, ponieważ IDE zna każde miejsce, w którym zmienna przechowuje instancję refaktoryzowanego obiektu.
Pisanie statyczne pozwala na większą użyteczność i łatwość konserwacji. Pisanie dynamiczne jest lepsze dla kodu jednorazowego. Załóżmy, że nowy programista wychodzi z ulicy i patrzy na istniejący fragment kodu. Jeśli kod jest wpisany statycznie, programista może, dwoma kliknięciami myszy, zbadać definicję klasy każdej ze zmiennych, wie, do czego służy klasa, wie, jakie inne metody i właściwości są dostępne. Jeśli kod jest wpisywany dynamicznie, programista musi użyć globalnego wyszukiwania, aby dowiedzieć się, co się dzieje.
źródło
Boy
klasę, ale wątpię, by mogła zrobić wszystko, co robi prawdziwy chłopiec. Jednak w twoim dynamicznym przykładzie (Obiekt jeździ ...) wiemy jedyną ważną rzecz o tym „chłopięcym” obiekcie - może on jeździć . To podstawowa filozofia języków dynamicznych. Ma + ve i -ve s. Który lubisz to twoja opinia.