Co je časná a pozdní vazba?
On 18 listopadu, 2020 by adminStále slyším o časné a pozdní vazbě, ale nerozumím tomu, co jsou zač. Našel jsem následující vysvětlení, kterému nerozumím:
Časná vazba odkazuje na přiřazení hodnot k proměnným během doby návrhu, zatímco pozdní vazba se týká přiřazení hodnot k proměnným za běhu.
Mohl by někdo definovat dva typy vazeb a porovnat je?
Komentáře
- doba kompilace vs doba běhu.
- Zde je dobré přečíst si toto téma: en.wikibooks.org/ wiki / Introduction_to_Programming_Languages / …
odpověď
Ve zmatku existují dva hlavní pojmy: vazba a načítání. Je sjednocen konceptem DataBinding, který je někde uprostřed a často dělá obojí. Po zvážení přidám ještě jeden koncept, abych dokončil trifecta, odeslal.
Typy
Pozdní vazba : typ není znám , dokud se proměnná nevykoná za běhu; obvykle prostřednictvím přiřazení, ale existují jiné prostředky k vynucení typu; dynamicky psané jazyky tomu říkají základní funkce, ale mnoho staticky psaných jazyků má nějakou metodu dosažení pozdní vazby.
Implementováno často pomocí [speciálních] dynamických typů, introspekce / reflexe, příznaků a možností kompilátoru nebo prostřednictvím virtuálních metod zapůjčením a rozšířením dynamického odesílání
Včasná vazba : typ je známý před provedením proměnné za běhu, obvykle prostřednictvím statických, deklarativních prostředků
Implementováno často pomocí standardních primitivních typů
Funkce
Static Dispatch : známá, konkrétní funkce nebo podprogram v době kompilace; je jednoznačné a odpovídá podpisu
Implementováno jako statické funkce; žádná metoda nemůže mít stejný podpis
Dynamic Dispatch : není konkrétní funkce nebo podprogram v době kompilace; určeno kontextem během provádění. Existují dva různé přístupy k „dynamickému odesílání“, které se liší podle toho, jaké kontextové informace se používají k výběru implementace příslušné funkce.
V single [ dynamický ] dispatch , k určení implementace příslušné funkce se použije pouze typ instance. Ve staticky psaných jazycích to v praxi znamená, že typ instance rozhoduje, která implementace metody se použije bez ohledu na typ odkazu uvedený při deklaraci / přiřazení proměnné. Protože k odvození příslušné implementace se používá pouze jediný typ – typ instance objektu, tento přístup se nazývá „jedno odeslání“.
Existuje také více [ dynamické ] odeslání , kde typy vstupních parametrů také pomáhají určit, kterou implementaci funkce zavolat. Protože více typů – jak typ instance , tak typy parametrů – ovlivňují která metoda implementace je vybrána, tento přístup se nazývá „vícenásobné odeslání“.
Implementováno jako virtuální nebo abstraktní funkce; další stopy zahrnují přepsané, skryté nebo stínované metody.
NB: Zda přetížení metody zahrnuje dynamické odesílání, je specifické pro jazyk. Například v Javě jsou přetížené metody odesílány staticky.
Hodnoty
Líné načítání : strategie inicializace objektu, která brání přiřazení hodnoty, dokud není potřeba ; umožňuje, aby byl objekt v podstatě platném, ale vědomě neúplném stavu a před načtením počkal, až budou data potřebná; často považováno za zvláště užitečné pro načítání velkých datových sad nebo čekání na externí zdroje tato kolekce (např. get_value_at, get_all_as atd.).Varianty zahrnují načítání meta informací o kolekci (například velikost nebo klíče), ale vynechání skutečných dat; také poskytuje mechanismus některým modulům runtime, který vývojářům poskytuje poměrně bezpečné a efektivní implementační schéma pro jednotlivce.
Eager Loading : strategie inicializace objektu, která okamžitě provede všechna přiřazení hodnot , aby měla všechna data potřebná k dokončení, než se bude považovat za platný stav.
Často implementováno co nejdříve poskytnout složeným objektům všechna jejich známá data, například během volání konstruktoru nebo inicializace
Data Binding : často zahrnuje vytvoření aktivního odkazu nebo mapy mezi dvěma kompatibilními informačními toky , takže změny jednoho se projeví zpět do druhého a naopak; aby byli kompatibilní, musí často mít společný základní typ nebo rozhraní.
Implementováno často jako pokus o čistší a konzistentní synchronizaci mezi různými aplikačními aspekty (např. view-model to view, model to controller atd.) a hovoří o koncepcích, jako je zdroj a cíl, koncové body, vazba / zrušení vazby, aktualizace a události jako on_bind, on_property_change, on_explicit, on_out_of_scope
EDITACE POZNÁMKA: Poslední hlavní úprava s uvedením popisu příkladů toho, jak k nim často dochází. Jednotlivé příklady kódu zcela závisí na implementaci / běhovém prostředí / platformě.
Komentáře
- Tato odpověď se zdá být příliš specifická pro objektově orientované jazyky.
- @Jack ‚ se tak necítím, myslím, že je to vynikající, který pokrývá mnoho aspektů.
Odpověď
Cokoli, o čem rozhodne kompilátor při kompilaci, může odkazovat na VČASNĚ / Zkompilovaný čas Vazba a vše, o čem bude rozhodnuto v RUNTIME se nazývá LATE / RUNTIME vazba.
Například
Metoda Přetížení a metody Přepsání .
1 ) V Přetížení metody volá vaše metoda metody ar O tom rozhodne kompilátor v tom smyslu, že která funkce se bude volat, rozhodne váš kompilátor v době kompilace. Proto je VČASNÉ ZÁVAZNOSTI .
2) Při přepsání metody se v RUNTIME rozhodne, která metoda je bude zavolán. Je tedy uváděno jako LATE BINDING .
Snažil jsem se, aby to bylo jednoduché a snadno dostupné. Doufám, že to pomůže.
Odpověď
Pozdní vazba je, když je chování vyhodnoceno za běhu. Je to nutné, když opravdu chcete určit, jak jednat na základě informací, které máte k dispozici pouze při spuštěném programu. Nejjasnějším příkladem je podle mého názoru mechanismus virtuálních funkcí, konkrétně v 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(); }
V tomto příkladu a->f()
skutečně zavolá void A::f()
, protože je to brzy (nebo staticky) ) vázán, a tak program za běhu myslí , že je to jen ukazatel na A
typ proměnné, zatímco a->g()
ve skutečnosti zavolá void B::g()
, protože kompilátor, když je g()
virtuální, vloží kód a vyhledá adresu správné funkce volat za běhu.
Komentáře
- “ Runtime „? Mluvíte ‚ o C ++. C ++ se kompiluje přímo do strojového kódu, ‚ k vyřešení nepotřebujete runtime virtuální metody.
- @tdammers C ++ ve skutečnosti potřebuje běhovou knihovnu, i když ne pro virtuální volání. Pokud budete číst pozorně, ‚ si všimnete, že tato odpověď říká, že kompilátor “ vloží kód, aby vyhledal adresu správné funkce [ …] za runtime „.
- No, ale ten “ kód vyhledat adresu správné funkce “ je v zásadě jen dereference dvoustupňového ukazatele s agnostickou funkcí a následným voláním funkce. Není zapojeno “ myšlení „; jediným důvodem, proč to spolehlivě funguje, je to, že kompilátor provádí kontrolu typu v době kompilace ; za běhu generovaný kód důvěřuje kompilátoru, že provedl domácí úkol kontroly typu. Pokud používáte nebezpečné obsazení (např.Ukazatel ve stylu C), můžete legálně zacházet s objekty C ++ jako s objektem nesprávné třídy, ale jejich vtables budou naprosto pokazeny a kód se prostě rozbije.
- @tdammers Snažil jsem se držet dál od tohoto druhu odpovědi, protože je to ‚ s implementačním detailem překladačů, což pro některé esoterické překladače může nebo nemusí být pravda. Důležitý je koncept.
- @tdammers A do “ doby běhu “ mám na mysli “ program za běhu „. Je zřejmé, že C ++ není ‚ t spravován. Ale protože jste mi ukázali, že to může způsobit zmatek, ‚ měním to na úplné znění.
Odpovědět
pokud znáte ukazatele funkcí, byl by to příklad. O definovaných funkcích lze říci, že jde o včasnou vazbu. vzhledem k tomu, že pokud použijete funkční ukazatele, jeho pozdní vazba.
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); }
zde funkce add a sub jsou funkce (jeho adresa je vázána při kompilaci time-linkeru)
ale ukazatel funkce je pozdě vazba fp může volat buď add, nebo sub v závislosti na volbě uživatele [za běhu].
Odpověď
Pouze časná a pozdní vazba dávají smysl v kontextu typů, a ne tak, jak to popisujete. Téměř všechny moderní jazyky jsou psány v tom smyslu, že všechny hodnoty mají pevné typy. Rozdíl nastává, když se podíváme na dynamicky a staticky psané jazyky. V dynamicky zadávaných jazycích proměnné nemají typy, takže mohou odkazovat na hodnoty jakéhokoli typu, což znamená, že když zavoláte metodu na objekt, na který odkazuje nějaká proměnná, jediným způsobem, jak zjistit, zda je toto volání platné, nebo ne vyhledat třídu pro objekt a zjistit, zda tato metoda skutečně existuje. To umožňuje některé skvělé věci, jako je přidávání nových metod do tříd za běhu, protože skutečné vyhledávání metod je odloženo až na poslední chvíli. Většina lidí nazývá tento stav záležitosti pozdní vazba.
Ve staticky zadaném jazyce mají proměnné typy a jednou deklarované nemohou odkazovat na žádnou hodnotu, která není stejného typu. To není striktně pravda, ale předpokládejme to zatím. Nyní, pokud víte, že proměnná bude vždy odkazovat pouze na hodnoty konkrétního typu, není důvod zjišťovat, zda je volání metody platné nebo ne za běhu, protože můžete určit platnost před spuštěním kódu. Toto se označuje jako časná vazba.
Příklad pro demonstraci pozdní vazby v ruby:
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
Výše uvedená posloupnost akcí není možné v jazyce jako Java, kde jsou všechny typy za běhu opraveny.
Odpověď
Místo toho, abych vám dal akademickou definici, se vám pokusí ukázat některé z rozdílů pomocí příkladu z reálného světa pomocí VBA:
Včasná vazba:
Dim x As FileSystemObject Set x = New FileSystemObject Debug.Print x.GetSpecialFolder(0)
To vyžaduje nastavení odkazu na komponentu „Microsoft Scripting Runtime“ v době návrhu . Má tu výhodu, že se vám chybová zpráva zobrazí již v době kompilace, když máte překlep v FileSystemObject
nebo v názvech metod jako GetSpecialFolder
.
Pozdní vazba
Dim x As Object Set x = CreateObject("Scripting.FileSystemObject") Debug.Print x.GetSpecialFolder(0)
To nevyžaduje předchozí nastavení odkazu, vytvoření instance a typ odhodlání se stane jen za běhu. Kompilátor si nebude stěžovat v době kompilace, když se pokusíte zavolat neexistující metodu x
, což povede k chybě za běhu pouze při provedení konkrétního řádku .
Nevýhodou pozdní vazby je tedy to, že zde nemáte žádnou silnou kontrolu typu. Ale to je také výhoda – řekněme, že máte komponentu, kde existuje několik verzí a každá novější verze poskytuje některé další funkce. (Příkladem v reálném světě jsou komponenty MS Office, jako je rozhraní Excel COM) Pozdní vazba umožňuje píšete kód, který funguje společně se všemi těmito verzemi – můžete nejprve určit konkrétní verzi komponenty a pokud zjistíte, že máte k dispozici pouze starší verzi, vyhněte se provádění volání funkcí, která s touto verzí nepracují.
Odpověď
Snad nejběžnějším příkladem pozdní vazby je řešení internetových adres URL. Podporuje dynamické systémy a velké systémy, aniž by se pokoušel propojit a svázat všechny stránky na světě, než se k nim dostanete, ale na druhou stranu to za běhu způsobí nějaké režijní náklady (vyhledávání DNS, mnohem méně směrování IP).
V tomto světle je většina druhů vazeb v jazykových prostředích víceméně brzy, v době kompilace nebo v době odkazu.
Každý druh má své náklady a výhody.
Komentáře
- Můžete vytvořit odkaz na tuto definici vazby?Neslyšel jsem o řešení internetových adres jako “ závazné „, i když je vazba aktem řešení jmen, předpokládám, že někdo argumentoval že koncept včasné / pozdní vazby lze použít k řešení URI na internetové adresy. Nejedná se však o běžnou interpretaci a koncept časné / pozdní vazby předchází době, kdy byly počítače běžně připojeny k internetu.
Napsat komentář