2016-08-16 1 views
2

Je continue à voir deux façons de définir la __index sur un métatable:différence dans Lua métatable __index positionnement

Account = {} 
Account.__index = Account 

function Account.create(balance) 
    local self = { balance = balance } 
    return setmetatable(self, Account) 
end 

Ou:

Account = {} 

function Account.create(balance) 
    local self = { balance = balance } 
    return setmetatable(self, { __index = Account }) 
end 

Je ne peut pas saisir tout à fait ce que la différence de comportement est entre les deux. Est-ce que quelqu'un peut m'éclairer?

Répondre

2

La différence est le nombre de tables créées et la chaîne de tables créée.

Dans le premier exemple, compte double d'un métatable Partagée pour tous cas ainsi que la destination de recherche pour la __index métaméthode. Création d'une chaîne comme:

instance -> Account, __index -> Account 

Dans le second exemple, chaque exemple retournée par la méthode create a son propre, métatable unique qui agit en tant que pont entre le exemple et la « classe ». La chaîne créée:

instance -> (anonymous, unique table), __index -> Account 

Parfois, vous verrez aussi des tables agissent comme leurs propres métatables:

Account = {} 

function Account.create(balance) 
    local self = { balance = balance, __index = Account } 
    return setmetatable(self, self) 
end 

Ce qui crée cette chaîne:

instance -> instance, __index -> Account 

Les avantages du premier et du troisième les styles sont des tables moins créées, ce qui peut simplifier certaines implémentations et réduire les empreintes de mémoire. Le deuxième style est sans doute plus robuste, puisque chaque instance obtient sa propre métatable qui peut ensuite être manipulée individuellement.

Le style que vous utilisez dépend vraiment des exigences de votre programme et de la facilité avec laquelle vous appliquez un style donné.

+1

Merci! C'était utile. Cependant, je ne comprends pas très bien l'option 3. Quel serait un cas d'utilisation typique? – tyrondis

+1

@tyrondis L'option trois est principalement un exemple de la façon dont _arbitrary_ peut être la métatable d'une table. Cela peut être utile dans la mesure où l'instance peut contrôler ses propres métaméthodes, sans une méta-donnée séparée comme dans l'option deux. [Voici un exemple] (https://github.com/Okahyphen/base/blob/master/src/base.lua), même si c'est un peu laconique. – Oka

+1

Gotcha! Merci de votre aide! – tyrondis