Je continue à entendre parler de liaison précoce et tardive, mais je ne comprends pas ce qu’elles sont. J'ai trouvé l'explication suivante que je ne comprends pas:
La liaison précoce fait référence à l'attribution de valeurs aux variables pendant la conception, tandis que la liaison tardive correspond à l'attribution de valeurs aux variables pendant l'exécution.
Quelqu'un pourrait-il définir les deux types de reliure et les comparer?
programming-languages
language-agnostic
SAMIR RATHOD
la source
la source
Réponses:
Il y a deux concepts principaux dans la confusion: la liaison et le chargement. Il est confondu avec le concept de DataBinding, qui est quelque part au milieu et fait souvent les deux. Après y avoir réfléchi, je vais ajouter un autre concept, pour compléter le triplé, dépêche.
Les types
Liaison tardive : le type est inconnu jusqu'à ce que la variable soit exercée pendant l'exécution; généralement par cession, mais il existe d'autres moyens de contraindre un type; les langages à typage dynamique appellent cela une fonctionnalité sous-jacente, mais de nombreux langages à typage statique ont une méthode permettant d'obtenir une liaison tardive
Mis en œuvre souvent à l'aide de types dynamiques [spéciaux], d'introspection / réflexion, d'indicateurs et d'options de compilation, ou via des méthodes virtuelles en empruntant et en étendant la répartition dynamique
Early Binding : le type est connu avant que la variable ne soit exercée pendant l'exécution, généralement par l'intermédiaire d'un moyen déclaratif statique
Implémenté souvent à l'aide de types primitifs standard
Les fonctions
Répartition statique : fonction ou sous-programme spécifique connu au moment de la compilation; il est sans ambiguïté et assorti de la signature
Implémenté en tant que fonctions statiques; aucune méthode ne peut avoir la même signature
Dispatch dynamique : pas une fonction ou un sous-programme spécifique au moment de la compilation; déterminé par le contexte lors de l'exécution. Il existe deux approches différentes de la "répartition dynamique", différenciées par les informations contextuelles utilisées pour sélectionner l'implémentation de la fonction appropriée.
Dans la répartition unique [ dynamique ] , seul le type de l'instance est utilisé pour déterminer l'implémentation de la fonction appropriée. Dans les langages à types statiques, cela signifie en pratique que le type d'instance décide quelle implémentation de la méthode est utilisée, quel que soit le type de référence indiqué lors de la déclaration / affectation de la variable. Étant donné que seul un type, le type de l'instance d'objet, est utilisé pour déduire l'implémentation appropriée, cette approche est appelée "envoi unique".
Il existe également de multiples répartitions [ dynamiques ] , où les types de paramètres d'entrée aident également à déterminer quelle implémentation de fonction appeler. Étant donné que plusieurs types, à la fois le type de l'instance et le ou les types de paramètre (s), influencent la mise en œuvre de la méthode sélectionnée, cette approche est appelée "envoi multiple".
Implémenté en tant que fonctions virtuelles ou abstraites; d'autres indices incluent les méthodes écrasées, cachées ou ombrées.
NB: Que la surcharge de méthode implique une dépêche dynamique dépend de la langue. Par exemple, en Java, les méthodes surchargées sont distribuées de manière statique.
Valeurs
Chargement paresseux : stratégie d'initialisation d'objet qui reporte l'attribution de valeur jusqu'au besoin ; permet à un objet d'être dans un état essentiellement valide mais sciemment incomplet et d'attendre que les données soient nécessaires avant de les charger; souvent trouvé particulièrement utile pour le chargement de grands ensembles de données ou l'attente de ressources externes
Implémenté souvent en ne chargeant pas délibérément une collection ou une liste dans un objet composite pendant les appels de constructeur ou d'initialisation jusqu'à ce qu'un appelant en aval demande à voir le contenu de cette collection (par exemple, get_value_at, get_all_as, etc.). Les variations incluent le chargement d'informations méta sur la collection (telles que la taille ou les clés), mais en omettant les données réelles; fournit également un mécanisme permettant à certaines exécutions de fournir aux développeurs un schéma d'implémentation singleton assez sûr et efficace
Eager Loading : stratégie d'initialisation d'objet qui exécute immédiatement toutes les attributions de valeur afin que toutes les données nécessaires soient complètes avant de se considérer comme étant dans un état valide.
Souvent mis en œuvre en fournissant à un objet composite toutes les données connues le plus rapidement possible, comme lors d'un appel ou d'une initialisation du constructeur
Liaison de données : implique souvent la création d'un lien actif ou d'une carte entre deux flux d'informations compatibles, de sorte que les modifications apportées à l'un soient reflétées dans l'autre, et inversement; afin d'être compatibles, ils doivent souvent avoir un type de base commun, ou une interface
Souvent implémentée dans le but de fournir une synchronisation plus propre et cohérente entre différents aspects de l’application (par exemple, le modèle de vue à afficher, le modèle sur le contrôleur, etc.), elle aborde des concepts tels que source et cible, points de terminaison, liaison / dissociation, mise à jour et événements tels que on_bind, on_property_change, on_explicit, on_out_of_scope
EDIT NOTE: Dernière édition majeure pour fournir une description d’exemples de la façon dont elles se produisent souvent. Les exemples de code particuliers dépendent entièrement de la mise en œuvre / exécution / plate-forme
la source
Tout ce qui est décidé par le compilateur pendant la compilation peut être référencé dans la liaison EARLY / COMPILE TIME et tout ce qui doit être décidé à RUNTIME est appelé liaison LATE / RUNTIME .
Par exemple,
Méthode surcharge et méthode Substitution .
1) Dans la méthode Surcharge de votre méthode, les appels aux méthodes sont décidés par le compilateur en ce sens que la fonction à appeler est déterminée par votre compilateur au moment de la compilation. D'où être tôt liaison .
2) En dérogation de méthode, il est décidé à RUNTIME quelle méthode sera appelée. Donc, il est fait référence à LATE BINDING .
J'ai essayé de rester simple et facile à obtenir. J'espère que cela t'aides.
la source
La liaison tardive se produit lorsque le comportement est évalué au moment de l'exécution. Il est nécessaire lorsque vous voulez vraiment déterminer comment agir en fonction des informations dont vous disposez uniquement lorsque le programme est en cours d'exécution. L'exemple le plus clair à mon avis est le mécanisme de la fonction virtuelle, en particulier en C ++.
Dans cet exemple,
a->f()
appelera en faitvoid A::f()
, car il est lié tôt (ou statiquement), et le programme au moment de l'exécution pense qu'il s'agit simplement d'un pointeur sur uneA
variable de type, alorsa->g()
qu'il appellera en faitvoid B::g()
, car le compilateur, voyantg()
est virtuel, injecte du code pour rechercher l'adresse de la fonction correcte à appeler au moment de l'exécution.la source
si vous êtes familier avec les pointeurs de fonction, ce serait un exemple. Les fonctions définies peuvent être considérées comme une liaison anticipée. alors que si vous utilisez des pointeurs de fonction, sa dernière liaison.
ici les fonctions add et sub sont des fonctions (son adresse est liée lors de la compilation du link-time)
mais le pointeur de la fonction lie tardivement, le fp peut appeler add ou sub en fonction du choix de l'utilisateur [au moment de l'exécution].
la source
La liaison précoce et tardive n’a de sens que dans le contexte des types et non dans la manière dont vous la décrivez. Presque toutes les langues modernes sont dactylographiées dans le sens où toutes les valeurs ont des types fixes. La différence intervient lorsque nous examinons des langages dynamiquement vs statiquement typés. Dans les langages à typage dynamique, les variables n'ont pas de types et peuvent donc faire référence à des valeurs de n'importe quel type. Cela signifie que lorsque vous appelez une méthode sur un objet référencé par une variable, le seul moyen de déterminer si cet appel est valide ou non est de: recherchez la classe pour l'objet et voyez si cette méthode existe réellement. Cela permet certaines choses intéressantes, telles que l'ajout de nouvelles méthodes aux classes au moment de l'exécution, car la recherche de la méthode réelle est différée jusqu'au dernier moment. La plupart des gens appellent cet état de fait une liaison tardive.
Dans un langage de type statique, les variables ont des types et, une fois déclarées, ne peuvent faire référence à aucune valeur qui ne soit pas du même type. Ce n'est pas strictement vrai, mais supposons-le pour le moment. Maintenant, si vous savez que la variable ne fera jamais référence qu'à des valeurs d'un type spécifique, il n'y a aucune raison de savoir si un appel de méthode est valide ou non au moment de l'exécution, car vous pouvez déterminer la validité avant que le code ne soit exécuté. Ceci est appelé liaison anticipée.
Un exemple pour démontrer une liaison tardive en rubis:
La séquence d'actions ci-dessus n'est pas possible dans un langage tel que Java où tous les types sont fixés au moment de l'exécution.
la source
Au lieu de vous donner une définition théorique, je vais essayer de vous montrer certaines des différences en utilisant un exemple concret utilisant VBA:
Reliure anticipée:
Cela nécessite qu'une référence soit définie au composant "Microsoft Scripting Runtime" au moment de la conception . Cela a l’avantage que vous obtenez déjà un message d’erreur au moment de la compilation lorsque vous avez une faute de frappe
FileSystemObject
ou des noms de méthodes tels queGetSpecialFolder
.Liaison tardive
Cela n'exige pas qu'une référence soit définie à l'avance, la création de l'instance et la détermination du type auront simplement lieu au moment de l'exécution. Le compilateur ne se plaindra pas au moment de la compilation lorsque vous essayez d'appeler une méthode non existante
x
, cela entraînera une erreur d'exécution uniquement lorsque la ligne spécifique est exécutée.Ainsi, l’inconvénient de la liaison tardive est que vous n’avez aucune vérification de type forte ici. Mais c’est aussi l’avantage: supposons que vous disposiez d’un composant comportant plusieurs versions et que chaque nouvelle version fournisse des fonctions supplémentaires. (Un exemple concret concerne les composants MS Office, tels que l'interface COM Excel). Une liaison tardive vous permet d'écrire du code qui fonctionne avec toutes ces versions. Vous pouvez d'abord déterminer la version du composant spécifique. Si vous découvrez que vous avez seulement une version plus ancienne disponible, évitez d'exécuter des appels de fonctions qui ne fonctionnent pas avec cette version.
la source
L’exemple le plus courant de liaison tardive est peut-être la résolution des URL Internet. Il prend en charge les systèmes dynamiques et les grands systèmes sans essayer de lier et de relier tous les sites du monde avant de pouvoir en joindre un, mais il entraîne en revanche un surcoût (recherche DNS, beaucoup moins de routage IP) lors de l'exécution.
De ce fait, la plupart des types de liaisons dans les environnements de langage sont plus ou moins précoces, au moment de la compilation ou de la liaison.
Chaque type a des coûts et des avantages.
la source