Mikä on varhainen ja myöhäinen sitova?
On marraskuu 18, 2020 by adminKuulen jatkuvasti varhaisesta ja myöhäisestä sitomisesta, mutta en ymmärrä mitä ne ovat. Löysin seuraavan selityksen, jota en ymmärrä:
Varhainen sitova viittaa arvojen osoittamiseen muuttujiin suunnitteluaikana, kun taas myöhäinen sitova viittaa arvojen osoittamiseen muuttujiin ajon aikana.
Voisiko joku määritellä nämä kaksi sidontatyyppiä ja verrata niitä?
Kommentit
- käännä aika vs ajonaika.
- Tässä on hyvä lukea aiheesta: fi.wikibooks.org/ wiki / Johdanto_ohjelmointikieliin / …
Vastaus
Hämmennyksessä on kaksi pääkäsitettä: sidonta ja lataus. Se sekoittuu DataBinding-käsitteeseen, joka on jossain keskellä usein molempia. Tarkasteltuani aion lisätä vielä yhden käsitteen, täydentää trifecta, lähetys.
Tyypit
Late Binding : tyyppiä ei tunneta , kunnes muuttujaa käytetään ajon aikana; yleensä tehtävän kautta, mutta on olemassa muita keinoja pakottaa tyyppi; dynaamisesti kirjoitetut kielet kutsuvat tätä taustalla olevaksi ominaisuudeksi, mutta monilla staattisesti kirjoitetuilla kielillä on jokin tapa saavuttaa myöhäinen sidonta. lainaamalla ja laajentamalla dynaamista lähetystä
Varhainen sidonta : tyyppi tunnetaan ennen muuttujan käyttöä ajon aikana, yleensä staattisilla, deklaratiivisilla keinoilla.
Toteutetaan usein tavallisilla primitiivityypeillä
Funktiot
Staattinen lähetys : tunnettu, erityinen toiminto tai aliohjelma käännösaikana; se on yksiselitteinen ja täsmää allekirjoituksen kanssa.
Toteutettu staattisina toimintoina; yhdelläkään menetelmällä ei voi olla samaa allekirjoitusta
Dynaaminen lähetys : ei tietty toiminto tai alirutiini kokoamisajankohtana; määrittelee konteksti suorituksen aikana. ”Dynaamiseen lähettämiseen” on kaksi erilaista lähestymistapaa, jotka erotetaan siitä, mitä asiayhteyteen liittyviä tietoja käytetään sopivan toiminnon toteutuksen valitsemiseen.
Kohdassa single [ dynamic ] dispatch , vain ilmentymän tyyppiä käytetään määrittämään sopiva toiminnon toteutus. Staattisesti kirjoitetuilla kielillä tämä tarkoittaa käytännössä sitä, että ilmentymätyyppi päättää käytetyn menetelmän toteutuksen riippumatta viitetyypistä, joka ilmoitetaan muuttujan ilmoitettaessa / osoitettaessa. Koska sopivan toteutuksen päättelemiseen käytetään vain yhtä tyyppiä – olioinstanssin tyyppiä, tätä lähestymistapaa kutsutaan ”yhdeksi lähetykseksi”.
Siellä on myös useita [ dynamic ] lähetys , jossa tuloparametrityypit auttavat myös määrittämään, minkä toiminnon toteutus kutsutaan. Koska useat tyypit – sekä ilmentymän tyyppi että – vaikuttavat parametrien tyyppeihin mikä menetelmän toteutustapa on valittu, tämä lähestymistapa kutsutaan nimellä ”useita lähetyksiä”.
Toteutettu virtuaalisina tai abstrakteina toimintoina; muita vihjeitä ovat ohitetut, piilotetut tai varjostetut menetelmät.
Huom: Onko menetelmän ylikuormituksessa mukana dynaaminen lähetys, on kielikohtainen. Esimerkiksi Java-sovelluksessa ylikuormitetut menetelmät lähetetään staattisesti.
Arvot
Laiska lataus : objektin alustusstrategia, joka lykkää arvonmääritystä tarpeen mukaan ; sallii kohteen olla olennaisesti pätevässä mutta tietoisesti epätäydellisessä tilassa ja odottaa, kunnes tietoja tarvitaan ennen sen lataamista; pidetään usein erityisen hyödyllisenä suurten tietojoukkojen lataamiseen tai odottamiseen ulkoisilla resursseilla.
Toteutetaan usein siten, että tarkoituksellisesti ei ladata kokoelmaa tai luetteloa yhdistelmäkohteeseen rakentajan tai alustuksen aikana, kunnes joku alavirran soittaja pyytää nähdä sisällön kyseinen kokoelma (esim. get_value_at, get_all_as jne.).Muunnelmat sisältävät metatietojen lataamisen kokoelmasta (kuten koon tai avaimet), mutta jättämällä pois todelliset tiedot; tarjoaa myös mekanismin joillekin ajoille, jotta kehittäjät saisivat melko turvallisen ja tehokkaan yksittäisen toteutuksen.
Innokas lataus : objektin alustusstrategia, joka suorittaa kaikki arvomääritykset välittömästi , jotta kaikki tarvittavat tiedot ovat täydelliset, ennen kuin hän pitää itseään kelvollisena.
Toteuttaa usein yhdistettyjen objektien toimittaminen kaikilla tunnetuilla tiedoillaan mahdollisimman pian, kuten rakentajan puhelun tai alustuksen aikana.
Tiedon sidonta : usein liittyy aktiivisen linkin tai kartan luominen kahden yhteensopivan tietovirran väliin niin, että yhden muutokset heijastuvat takaisin toiseen ja päinvastoin; Jotta ne olisivat yhteensopivia, heillä on usein oltava yhteinen perustyyppi tai käyttöliittymä.
Toteutetaan usein pyrkimyksenä tarjota puhtaampi ja johdonmukaisempi synkronointi eri sovellusten näkökohtien välillä (esim. tarkasteltava näkymä, malli ohjaimelle jne.) ja puhuu käsitteistä, kuten lähde ja kohde, päätepisteet, sidonta / irrotus, päivitys ja tapahtumista, kuten on_bind, on_property_change, on_explicit, on_out_of_scope
MUOKKAA HUOMAUTUS: Viimeinen merkittävä muokkaus antaa kuvauksen esimerkkejä siitä, kuinka näitä usein tapahtuu. Erityiset koodiesimerkit riippuvat kokonaan implementaatiosta / ajonaikaisesta / alustasta.
Kommentit
- Tämä vastaus vaikuttaa liian spesifiseltä olio-kielille.
- @Jack En tunne ’ tätä mieltä, mielestäni tämä on erinomainen, joka kattaa monia näkökohtia.
Vastaus
Kaikki, minkä kääntäjä päättää kääntämisen aikana, voi viitata AIKAISEEN / KÄÄNTÖAIKAAN Sitomista ja kaikkea, mikä on päätettävä RUNTIME , kutsutaan nimellä LATE / RUNTIME sidonta.
Esimerkiksi
Menetelmä Ylikuormitus ja menetelmä .
1 ) Menetelmän -menetelmän ylikuormitus -metodissa kutsutaan menetelmiin ar Kääntäjä on päättänyt siinä mielessä, että mikä toiminto kutsutaan, kääntäjä päättää kääntöhetkellä. Tästä syystä se on AIKAISESIDONTOINTI .
2) Menetelmän ohitusohjelmassa RUNTIME päätetään, mikä menetelmä on soitetaan. Joten se tarjotaan nimellä LATE BINDING .
Yritti pitää sen yksinkertaisena ja helposti hankittavana. Toivottavasti tämä auttaa.
Vastaus
Myöhäinen sitoutuminen on, kun käyttäytymistä arvioidaan ajon aikana. Se on välttämätöntä, kun haluat todellakin päättää, miten toimia tietojen perusteella, jotka sinulla on vain ohjelman ollessa käynnissä. Mielestäni selkein esimerkki on virtuaalitoimintamekanismi, erityisesti C ++: ssa.
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(); }
Tässä esimerkissä a->f()
kutsuu itse asiassa void A::f()
, koska se on aikaisin (tai staattisesti) ) sidottu, joten ohjelma ajon aikana ajattelee että se on vain osoitin A
-tyyppiselle muuttujalle, kun taas a->g()
kutsuu itse asiassa void B::g()
, koska kääntäjä, nähdessään g()
on virtuaalinen, syöttää koodia etsimään oikean toiminnon osoitteen soittaa ajon aikana.
Kommentit
- ” Suorituksen aika ”? ’ puhut uudelleen C ++: sta. C ++ kääntyy suoraan konekoodiksi, se ei tarvitse ajonaikaa ratkaistakseen ’ virtuaaliset menetelmät.
- @tdammers C ++ tarvitsee itse asiassa ajoaikakirjaston, vaikkakaan ei virtuaalipuheluita varten. Jos luet huolellisesti, ’ huomaat, että tässä vastauksessa sanotaan, että kääntäjä ” pistää koodia etsimään oikean toiminnon osoitteen …] at ajonaikainen ”.
- No, mutta se ” -koodi oikean funktion osoitteen etsiminen ” on pohjimmiltaan vain tyypin agnostinen kaksivaiheinen osoittimen poikkeama, jota seuraa toimintokutsu. ” ei ole mukana ajattelua ”; ainoa syy siihen, että se toimii luotettavasti, johtuu siitä, että kääntäjä tarkistaa tyyppitarkistuksen kääntöhetkellä ; ajon aikana luotu koodi luottaa kääntäjään suorittaneen tyyppitarkastuksen kotitehtävät. Jos käytät vaarallisia heittoja (esim.C-tyylinen osoitin heittää), voit kohdella laillisesti C ++ -objekteja väärän luokan kohteena, mutta niiden vtabelit ovat täysin sekaisin ja koodi vain rikkoutuu.
- @tdammers Yritin pysyä poissa tällaisesta vastauksesta, koska se ’ on yksityiskohta kääntäjistä, mikä saattaa olla totta joillekin esoteerisille kääntäjille. Tärkeää on käsite.
- @tdammers Ja ” mukaan ajonaikainen ” tarkoitan ” ohjelma ajon aikana ”. C ++ ei selvästikään ole ’ hallinnassa. Mutta koska näytit minulle, se voi aiheuttaa hämmennystä, muutan sen sanamuotoon.
Vastaa h2 ’ m. >
jos olet perehtynyt funktion osoittimiin, tämä olisi esimerkki. Määritettyjen toimintojen voidaan sanoa olevan varhaisia sitovia. Kun taas käytät toimintoa, osoitin viivästyy.
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); }
tässä funktiot add ja sub ovat funktioita (sen osoite on sidottu käännettäessä aikalinkkiä)
mutta funktion osoitin on myöhässä fp: n sitominen voi kutsua joko lisäystä tai ali käyttäjän valinnan mukaan [ajonaikaisesti].
Vastaa
Vain varhainen ja myöhäinen sidonta on järkevää tyyppien yhteydessä eikä tavalla, jolla kuvaat sitä. Melkein kaikki modernit kielet kirjoitetaan siinä mielessä, että kaikilla arvoilla on kiinteät tyypit. Ero tulee, kun tarkastelemme dynaamisesti vs. staattisesti kirjoitettuja kieliä. Dynaamisesti kirjoitetuilla kielillä muuttujilla ei ole tyyppejä, joten ne voivat viitata minkä tahansa tyyppisiin arvoihin, mikä tarkoittaa, että kun kutsut jotain menetelmää objektille, johon jokin muuttuja viittaa, ainoa tapa määrittää, onko puhelu kelvollinen vai ei, on etsi objektin luokka ja katso, onko menetelmä todellakin olemassa. Tämä sallii joitain hienoja asioita, kuten uusien menetelmien lisäämisen luokkiin ajon aikana, koska varsinaista menetelmän hakua lykätään viimeiseen hetkeen asti. Useimmat ihmiset kutsuvat tätä tilaa asioiden myöhäinen sitominen.
Staattisesti kirjoitetussa kielessä muuttujilla on tyyppejä, ja kun ne on ilmoitettu, ne eivät voi viitata arvoihin, jotka eivät ole samantyyppisiä. Tämä ei ole ehdottomasti totta, mutta antaa sen olettaa toistaiseksi. Jos tiedät, että muuttuja viittaa vain tietyntyyppisiin arvoihin, ei ole mitään syytä selvittää, onko menetelmän kutsu kelvollinen vai ei ajon aikana, koska voit määrittää kelvollisuuden ennen kuin koodi on koskaan suoritettu. Tätä kutsutaan varhaiseksi sitomiseksi.
Esimerkki myöhäisen sitoutumisen osoittamisesta rubiinissa:
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
Yllä oleva toimintosarja ei ole mahdollista kielellä Java, jossa kaikki tyypit on kiinteä ajon aikana.
Vastaa
Sen sijaan, että annat sinulle akateemisen määritelmän I yrittää näyttää sinulle joitain eroja käyttämällä tosielämän esimerkkiä VBA: n avulla:
Varhainen sidonta:
Dim x As FileSystemObject Set x = New FileSystemObject Debug.Print x.GetSpecialFolder(0)
Tämä edellyttää, että viite asetetaan ”Microsoft Scripting Runtime” -komponenttiin suunnitteluaikana . Sen etuna on, että saat virheilmoituksen jo kääntämisajankohtana, kun kirjoitusvirhe on FileSystemObject
tai menetelmän nimissä, kuten GetSpecialFolder
.
Myöhäinen sidonta
Dim x As Object Set x = CreateObject("Scripting.FileSystemObject") Debug.Print x.GetSpecialFolder(0)
Tämä ei edellytä etukäteen asetettavaa viitettä, ilmentymän luonnia ja tyyppiä päättäväisyys tapahtuu vain ajon aikana. Kääntäjä ei valittaa käännösaikana, kun yrität kutsua olematonta menetelmää x
, tämä johtaa ajonaikaisvirheeseen vain, kun tietty rivi suoritetaan .
Myöhäisen sidonnan haittana on, että sinulla ei ole mitään vahvaa tyyppitarkistusta täällä. Mutta se on myös etu – sanotaan, että sinulla on komponentti, jossa on useita versioita, ja jokainen uudempi versio tarjoaa joitain lisätoimintoja. (Todellisessa esimerkissä ovat MS Office-komponentit, kuten Excel COM -käyttöliittymä). kirjoitat koodia, joka toimii kaikkien näiden versioiden kanssa – voit ensin määrittää tietyn komponenttiversion, ja jos huomaat, että sinulla on käytettävissä vain vanhempi versio, vältä suorittamasta toimintokutsuja, jotka eivät toimi kyseisen version kanssa. / p>
Vastaus
Ehkä yleisin esimerkki myöhäisestä sidonnasta on Internet-URL-osoitteiden ratkaiseminen. Se tukee dynaamisia järjestelmiä ja suuria järjestelmiä yrittämättä linkittää ja sitoa kaikkia sivustoja maailmassa, ennen kuin pääset mihinkään, mutta toisaalta siitä aiheutuu jonkin verran yleiskustannuksia (DNS-haku, paljon vähemmän IP-reititystä) ajon aikana.
Tässä valossa useimmat kieliympäristöjen sidontamuodot ovat enemmän tai vähemmän varhaisia, kokoamis- tai linkitysaikana.
Jokaisella lajilla on kustannuksia ja hyötyjä.
Kommentit
- Voitteko sijoittaa viitteen tälle sidonnan määritelmälle?En ole kuullut Internet-osoitteiden ratkaisemisesta ” sitovina ”, vaikka koska sitominen on nimien ratkaisemista, oletan, että joku on väittänyt että varhaisen / myöhäisen sitoutumisen käsitettä voidaan soveltaa URI: n ratkaisemiseen Internet-osoitteisiin. Mutta tämä ei ole yleinen tulkinta, ja varhaisen / myöhäisen sidonnan käsite edeltää aikaa, jolloin tietokoneet olivat yleisesti yhteydessä Internetiin.
jos olet perehtynyt funktion osoittimiin, tämä olisi esimerkki. Määritettyjen toimintojen voidaan sanoa olevan varhaisia sitovia. Kun taas käytät toimintoa, osoitin viivästyy.
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); }
tässä funktiot add ja sub ovat funktioita (sen osoite on sidottu käännettäessä aikalinkkiä)
mutta funktion osoitin on myöhässä fp: n sitominen voi kutsua joko lisäystä tai ali käyttäjän valinnan mukaan [ajonaikaisesti].
Vain varhainen ja myöhäinen sidonta on järkevää tyyppien yhteydessä eikä tavalla, jolla kuvaat sitä. Melkein kaikki modernit kielet kirjoitetaan siinä mielessä, että kaikilla arvoilla on kiinteät tyypit. Ero tulee, kun tarkastelemme dynaamisesti vs. staattisesti kirjoitettuja kieliä. Dynaamisesti kirjoitetuilla kielillä muuttujilla ei ole tyyppejä, joten ne voivat viitata minkä tahansa tyyppisiin arvoihin, mikä tarkoittaa, että kun kutsut jotain menetelmää objektille, johon jokin muuttuja viittaa, ainoa tapa määrittää, onko puhelu kelvollinen vai ei, on etsi objektin luokka ja katso, onko menetelmä todellakin olemassa. Tämä sallii joitain hienoja asioita, kuten uusien menetelmien lisäämisen luokkiin ajon aikana, koska varsinaista menetelmän hakua lykätään viimeiseen hetkeen asti. Useimmat ihmiset kutsuvat tätä tilaa asioiden myöhäinen sitominen.
Staattisesti kirjoitetussa kielessä muuttujilla on tyyppejä, ja kun ne on ilmoitettu, ne eivät voi viitata arvoihin, jotka eivät ole samantyyppisiä. Tämä ei ole ehdottomasti totta, mutta antaa sen olettaa toistaiseksi. Jos tiedät, että muuttuja viittaa vain tietyntyyppisiin arvoihin, ei ole mitään syytä selvittää, onko menetelmän kutsu kelvollinen vai ei ajon aikana, koska voit määrittää kelvollisuuden ennen kuin koodi on koskaan suoritettu. Tätä kutsutaan varhaiseksi sitomiseksi.
Esimerkki myöhäisen sitoutumisen osoittamisesta rubiinissa:
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
Yllä oleva toimintosarja ei ole mahdollista kielellä Java, jossa kaikki tyypit on kiinteä ajon aikana.
Sen sijaan, että annat sinulle akateemisen määritelmän I yrittää näyttää sinulle joitain eroja käyttämällä tosielämän esimerkkiä VBA: n avulla:
Varhainen sidonta:
Dim x As FileSystemObject Set x = New FileSystemObject Debug.Print x.GetSpecialFolder(0)
Tämä edellyttää, että viite asetetaan ”Microsoft Scripting Runtime” -komponenttiin suunnitteluaikana . Sen etuna on, että saat virheilmoituksen jo kääntämisajankohtana, kun kirjoitusvirhe on FileSystemObject
tai menetelmän nimissä, kuten GetSpecialFolder
.
Myöhäinen sidonta
Dim x As Object Set x = CreateObject("Scripting.FileSystemObject") Debug.Print x.GetSpecialFolder(0)
Tämä ei edellytä etukäteen asetettavaa viitettä, ilmentymän luonnia ja tyyppiä päättäväisyys tapahtuu vain ajon aikana. Kääntäjä ei valittaa käännösaikana, kun yrität kutsua olematonta menetelmää x
, tämä johtaa ajonaikaisvirheeseen vain, kun tietty rivi suoritetaan .
Myöhäisen sidonnan haittana on, että sinulla ei ole mitään vahvaa tyyppitarkistusta täällä. Mutta se on myös etu – sanotaan, että sinulla on komponentti, jossa on useita versioita, ja jokainen uudempi versio tarjoaa joitain lisätoimintoja. (Todellisessa esimerkissä ovat MS Office-komponentit, kuten Excel COM -käyttöliittymä). kirjoitat koodia, joka toimii kaikkien näiden versioiden kanssa – voit ensin määrittää tietyn komponenttiversion, ja jos huomaat, että sinulla on käytettävissä vain vanhempi versio, vältä suorittamasta toimintokutsuja, jotka eivät toimi kyseisen version kanssa. / p>
Ehkä yleisin esimerkki myöhäisestä sidonnasta on Internet-URL-osoitteiden ratkaiseminen. Se tukee dynaamisia järjestelmiä ja suuria järjestelmiä yrittämättä linkittää ja sitoa kaikkia sivustoja maailmassa, ennen kuin pääset mihinkään, mutta toisaalta siitä aiheutuu jonkin verran yleiskustannuksia (DNS-haku, paljon vähemmän IP-reititystä) ajon aikana.
Tässä valossa useimmat kieliympäristöjen sidontamuodot ovat enemmän tai vähemmän varhaisia, kokoamis- tai linkitysaikana.
Jokaisella lajilla on kustannuksia ja hyötyjä.
Kommentit
- Voitteko sijoittaa viitteen tälle sidonnan määritelmälle?En ole kuullut Internet-osoitteiden ratkaisemisesta ” sitovina ”, vaikka koska sitominen on nimien ratkaisemista, oletan, että joku on väittänyt että varhaisen / myöhäisen sitoutumisen käsitettä voidaan soveltaa URI: n ratkaisemiseen Internet-osoitteisiin. Mutta tämä ei ole yleinen tulkinta, ja varhaisen / myöhäisen sidonnan käsite edeltää aikaa, jolloin tietokoneet olivat yleisesti yhteydessä Internetiin.
Vastaa