Ce este legarea timpurie și tardivă?
On noiembrie 18, 2020 by adminÎncă aud despre legarea timpurie și tardivă, dar nu înțeleg ce sunt acestea. Am găsit următoarea explicație pe care nu o înțeleg:
Legarea timpurie se referă la atribuirea valorilor variabilelor în timpul proiectării, în timp ce legarea tardivă se referă la atribuirea valorilor la variabile în timpul duratei de executare.
Poate cineva să definească cele două tipuri de legare și să le compare?
Comentarii
- timp de compilare vs timp de execuție.
- Iată o citire bună despre subiect: en.wikibooks.org/ wiki / Introduction_to_Programming_Languages / …
Răspuns
Există două concepte majore în confuzie: legare și încărcare. Este confundat cu conceptul DataBinding, care se află undeva la mijloc de multe ori. După ce am analizat-o, voi adăuga încă un concept, pentru a finaliza trifecta, expediere.
Tipuri
Late Binding : tipul este necunoscut până când variabila este exercitată în timpul rulării; de obicei prin atribuire, dar există și alte mijloace de constrângere a unui tip; limbile tipizate dinamic numesc aceasta o caracteristică de bază, dar multe limbi tipizate static au o metodă de realizare a legării tardive
Implementate adesea folosind tipuri dinamice [speciale], introspecție / reflecție, steaguri și opțiuni de compilare sau prin metode virtuale împrumutând și extinzând expedierea dinamică
Legare timpurie : tipul este cunoscut înainte ca variabila să fie exercitată în timpul rulării, de obicei printr-un mijloc static, declarativ
Implementat adesea folosind tipuri primitive standard
Funcții
Dispecerat static : funcție cunoscută, specifică sau subrutină la momentul compilării; nu este ambiguu și se potrivește cu semnătura
Implementat ca funcții statice; nicio metodă nu poate avea aceeași semnătură
Dynamic Dispatch : nu este o funcție specifică sau subrutină la momentul compilării; determinat de contextul din timpul executării. Există două abordări diferite ale „expediției dinamice”, care se disting prin informațiile contextuale utilizate pentru a selecta implementarea funcției adecvate.
În single [ dynamic ] dispatch , numai tipul instanței este utilizat pentru a determina implementarea funcției corespunzătoare. În limbile tipizate static, ceea ce înseamnă acest lucru în practică este că tipul instanței decide ce metodă de implementare este utilizată, indiferent de tipul de referință indicat atunci când variabila este declarată / atribuită. Deoarece doar un singur tip – tipul instanței de obiect – este utilizat pentru a deduce implementarea adecvată, această abordare se numește „expediere unică”.
Există și multiple [ dynamic ] expediere , unde tipurile de parametri de intrare ajută, de asemenea, la determinarea implementării funcției care trebuie apelată. Deoarece mai multe tipuri – atât tipul instanței , cât și tipul (tipurile) parametrului (parametrilor) – influențează care metodă de implementare este selectată, această abordare este denumită „expediere multiplă”.
Implementată ca funcții virtuale sau abstracte; alte indicii includ metode suprascrise, ascunse sau umbrite.
NB: Dacă supraîncărcarea metodei implică sau nu expediere dinamică este specifică limbii. De exemplu, în Java, metodele supraîncărcate sunt expediate static.
Valori
Lazy Loading : strategie de inițializare a obiectelor care definește atribuirea valorii până când este necesar ; permite unui obiect să se afle într-o stare esențial validă, dar cu bună știință incompletă și să aștepte până când datele sunt necesare înainte de a le încărca; adesea găsit deosebit de util pentru încărcarea seturilor de date mari sau așteptarea resurselor externe
Implementat adesea prin încărcarea intenționată a unei colecții sau a unei liste într-un obiect compozit în timpul constructorului sau inițializarea apelurilor până când un apelant din aval cere să vadă conținutul acea colecție (de exemplu, get_value_at, get_all_as etc.).Variațiile includ încărcarea informațiilor meta despre colecție (cum ar fi dimensiunea sau cheile), dar omiterea datelor reale; oferă, de asemenea, un mecanism pentru unele runtimes pentru a oferi dezvoltatorilor o schemă de implementare singleton destul de sigură și eficientă
Eager Loading : strategie de inițializare a obiectelor care efectuează imediat toate atribuirile de valoare pentru a avea toate datele necesare completării înainte de a se considera într-o stare validă.
Implementat adesea de furnizarea unui obiect compozit cu toate datele cunoscute cât mai curând posibil, cum ar fi în timpul unui apel constructor sau inițializare
Legare date : implică adesea crearea unei legături active sau a unei hărți între două fluxuri de informații compatibile , astfel încât modificările la unul să fie reflectate înapoi în celălalt și invers; pentru a fi compatibili, adesea trebuie să aibă un tip de bază comun sau o interfață
Implementată adesea ca o încercare de a oferi o sincronizare mai curată și consecventă între diferitele aspecte ale aplicației (de exemplu, vizualizați modelul pentru vizualizare, modelul către controler etc.) și vorbește despre concepte precum sursă și țintă, puncte finale, legare / dezlegare, actualizare și evenimente precum on_bind, on_property_change, on_explicit, on_out_of_scope
NOTĂ EDITARE: Ultima modificare majoră pentru a furniza descrierea de exemple despre modul în care acestea apar adesea. Exemplele de coduri particulare depind în totalitate de implementare / runtime / platformă
Comentarii
- Acest răspuns pare prea specific limbajelor orientate obiect.
- @Jack Nu ‘ mă simt așa, cred că acesta este un excelent care acoperă multe aspecte.
Răspuns
Orice lucru care este decis de compilator în timpul compilării poate fi consultat la TIMP PRIMAR / COMPILAT Obligatoriu și orice trebuie decis la RUNTIME se numește LATE / RUNTIME obligatoriu.
De exemplu,
Metoda Suprasolicitare și metodă Suprascriere .
1 ) În Supraîncărcarea metodelor metoda dvs. apelează la metodele ar Am decis de compilator în sensul că funcția care va fi apelată este decisă de compilator la momentul compilării. Prin urmare, fiind EARLY BINDING .
2) În metoda Overriding, se decide la RUNTIME care metodă este va fi chemat. Deci, este denumit LATE BINDING .
Am încercat să îl păstrăm simplu și ușor de obținut. Sper că acest lucru vă va ajuta.
Răspuns
Legarea tardivă este atunci când comportamentul este evaluat în timpul rulării. Este necesar atunci când doriți să determinați cum să acționați pe baza informațiilor pe care le aveți numai atunci când programul rulează. Cel mai clar exemplu în opinia mea este mecanismul funcției virtuale, în special în C ++.
class A { public: void f() {} virtual void g() {} }; class B : public A { void f() {} virtual void g() {} }; int main() { A* a = new B; a->f(); a->g(); }
În acest exemplu, a->f()
va apela de fapt void A::f()
, deoarece este devreme (sau static) ) legat, și astfel programul în timp de execuție crede este doar un pointer către o variabilă de tip A
, în timp ce a->g()
va apela de fapt void B::g()
, deoarece compilatorul, văzând g()
este virtual, injectează cod pentru a căuta adresa funcției corecte pentru a apela la runtime.
Comentarii
- ” Runtime „? ‘ vorbiți despre C ++. C ++ compilează direct la codul mașinii, nu ‘ nu aveți nevoie de un timp de rulare pentru a rezolva metode virtuale.
- @tdammers C ++ are de fapt nevoie de o bibliotecă de timp de rulare, deși nu pentru apeluri virtuale. Dacă citiți cu atenție, ‘ veți observa că acest răspuns spune că compilatorul ” injectează cod pentru a căuta adresa funcției corecte [ …] la runtime „.
- Ei bine, dar acel cod ” a căuta adresa funcției corecte ” este în esență doar o dereferențare a indicatorului cu două etape de tip agnostic, urmată de un apel de funcție. Nu există ” gândire ” implicată; singurul motiv pentru care funcționează în mod fiabil este că compilatorul face verificarea tipului la compilare ; în timpul rulării, codul generat are încredere în compilator că a făcut temele de verificare a tipului. Dacă utilizați proiecții nesigure (de ex.Pointer-uri în stil C), puteți puteți trata în mod legal obiectele C ++ ca obiect al clasei greșite, dar tabelele lor vor fi complet încurcate, iar codul se rupe.
- @tdammers Am încercat să stau departe de acest tip de răspuns, deoarece este ‘ un detaliu de implementare a compilatoarelor, care ar putea sau nu ar fi adevărat pentru un compilator ezoteric. Ceea ce contează este conceptul.
- @tdammers Și prin ” timpul de execuție ” mă refer la ” programul la runtime „. Evident, C ++ nu este gestionat ‘. Dar, de vreme ce mi-ați arătat că poate provoca confuzie, ‘ îl schimb pe textul complet.
Răspuns
dacă sunteți familiarizat cu indicatorii de funcție, acesta ar fi un exemplu. Funcțiile definite se pot spune că sunt obligatorii timpurii. întrucât dacă utilizați indicii funcționale, legarea tardivă a acestuia.
int add(int x,int y) { return x+y; } int sub(int x,int y) { return x-y; } int main() { //get user choice int(*fp)(int,int); //if add fp=add; //else if sub fp=sub; cout<<fp(2,2); }
aici funcțiile adaugă și sub sunt funcții (adresa sa este legată la compilarea timp-linker)
dar indicatorul funcției este târziu legarea fp poate apela fie add, fie sub, în funcție de alegerea utilizatorului [la runtime].
Răspuns
Doar legarea timpurie și tardivă are sens în contextul tipurilor și nu în modul în care îl descrieți. Aproape toate limbile moderne sunt tastate în sensul că toate valorile au tipuri fixe. Diferența apare atunci când ne uităm la limbajele dinamic față de cele scrise static. În limbile cu variații dinamice, variabilele nu au tipuri, astfel încât să poată face referire la valori de orice tip și asta înseamnă că atunci când apelezi o metodă pe un obiect la care se referă o variabilă, singurul mod de a determina dacă acel apel este valid sau nu este să căutați clasa pentru obiect și vedeți dacă metoda respectivă există de fapt. Acest lucru permite anumite lucruri interesante, cum ar fi adăugarea de noi metode la clase în timpul rulării, deoarece căutarea metodelor reale este amânată până în ultimul moment. Majoritatea oamenilor numesc această stare de affari de legare târzie.
Într-un limbaj tipizat static variabilele au tipuri și odată declarate nu se pot referi la nicio valoare care nu este de același tip. Acest lucru nu este strict adevărat, dar să presupunem că pentru moment. Acum, dacă știți că variabila se va referi doar la valori de un anumit tip, atunci nu există niciun motiv pentru a afla dacă un apel de metodă este valid sau nu în timpul rulării, deoarece puteți determina validitatea înainte ca codul să fie executat vreodată. Aceasta este denumită legare timpurie.
Un exemplu pentru a demonstra legarea tardivă în rubin:
a = 1 # a is an integer at this point a.succ # asking for its successor is valid class A def method_a # some code end end a = A.new a.method_a # this is also valid a.succ # this is not valid class A # we can re-open the class and add a method def succ # some more code end end a.succ # now this is valid
Secvența de acțiuni de mai sus nu este posibil într-un limbaj precum Java în care toate tipurile sunt fixate în timpul rulării.
Răspuns
În loc să vă dau o definiție academică I va încerca să vă arate câteva dintre diferențe folosind un exemplu din lumea reală folosind VBA:
Legare timpurie:
Dim x As FileSystemObject Set x = New FileSystemObject Debug.Print x.GetSpecialFolder(0)
Aceasta necesită setarea unei referințe la componenta „Microsoft Scripting Runtime” la ora de proiectare . Are avantajul că primiți un mesaj de eroare deja în momentul compilării, când aveți o greșeală de scriere în FileSystemObject
sau nume de metode precum GetSpecialFolder
.
Legare tardivă
Dim x As Object Set x = CreateObject("Scripting.FileSystemObject") Debug.Print x.GetSpecialFolder(0)
Acest lucru nu necesită o referință care să fie setată în prealabil, crearea și tipul instanței determinarea se va întâmpla doar în timpul rulării. Compilatorul nu se va plânge la compilare atunci când încercați să apelați o metodă inexistentă de x
, acest lucru va duce la o eroare în timpul rulării numai atunci când linia specifică este executată .
Deci, dezavantajul legării târzii este că nu aveți niciun tip de verificare puternică aici. Dar acesta este și avantajul – să spunem că aveți o componentă în care există mai multe versiuni și fiecare versiune mai nouă oferă câteva funcții suplimentare. (Un exemplu real este componentele MS Office, cum ar fi interfața Excel COM) Legarea târzie permite scrieți cod care funcționează împreună cu toate acele versiuni – puteți determina mai întâi versiunea specifică a componentei și, dacă aflați că aveți disponibilă doar o versiune mai veche, evitați să executați apeluri de funcții care nu funcționează cu acea versiune.
Răspuns
Poate că cel mai frecvent exemplu de legare tardivă este rezolvarea adreselor URL de Internet. Acceptă sisteme dinamice și sisteme mari, fără a încerca să conecteze și să lege fiecare site din lume înainte de a putea ajunge la vreunul, dar, pe de altă parte, suportă unele cheltuieli generale (căutare DNS, mult mai puțin rutare IP) în timpul rulării.
În lumina respectivă, majoritatea varietăților de legături în mediile lingvistice sunt mai mult sau mai puțin timpurii, la momentul compilării sau la momentul conectării.
Fiecare tip are costuri și beneficii.
Comentarii
- Puteți găsi o referință pentru această definiție a legării?Nu am auzit de rezolvarea adreselor de internet ca ” obligatoriu „, deși legarea este actul rezolvării numelor, presupun că cineva a argumentat că conceptul de legare timpurie / tardivă poate fi aplicat la rezolvarea URI la adrese de internet. Dar aceasta nu este o interpretare obișnuită, iar conceptul de legare timpurie / târzie precedă perioada în care computerele erau conectate în mod obișnuit la internet.
Lasă un răspuns