![]() |
Programmation en language LUA |
Table Faibles D'instruction |
Il est utile de comprendre la
collection d'ordures avant de lire ce cours
d'instruction. Le GarbageCollectionTutorial fournit une introduction.
Dans les langages de programmation tels que Lua qui utilisent la collection d'ordures, une référence à un objet serait faible si elle n'empêche pas la collection de l'objet. Les références faibles sont utiles pour déterminer quand un objet a été rassemblé et pour cacher objectent sans empêcher leur collection.
Plutôt que fournissez une interface à différentes références faibles, Lua fournit une construction de plus haut niveau appelée une table faible. Dans une table faible les clefs et/ou les valeurs sont des références faibles. Si une clef ou une valeur d'une telle table est rassemblée, cette entrée de la table sera enlevée.
Voici un complet, bien que très arrangé, exemple d'une table faible dans l'action :
t = {} setmetatable(t, {mode de __ = 'v '}) font someval local = {} t['foo '] = collectgarbage() someval d'extrémité pour k, v dans t font le print(k, v) extrémité
Essayez cet exemple avec et sans collectgarbage()
appel a commenté dehors. Avec l'appel, le
programme n'imprimera rien, car la valeur de la seule entrée de table
sera rassemblée.
Une table faible est créée en plaçant son metatable à
un metatable qui a __mode
un champ. Dans l'exemple
ci-dessus nous permettons des valeurs faibles avec v
(est k
de même pour des clefs). Le but de créer la
valeur d'essai someval
comme variable locale dans do
un
bloc est de sorte que nous puissions forcer la collection d'ordures de
la valeur plus tard avec un appel à collectgarbage
. Notez cela
qui emploie une coquille telle qu'une corde ou le nombre pour someval
n'aurait pas fonctionné, car les coquilles ne sont
jamais des ordures rassemblées.
Notez qu'une fois qu'une table a été employée car un
metatable alors il n'est pas légal pour changer le champ __mode
des metatable (pour les restrictions exactes voir la
section 2.9.2 du manuel de référence de Lua 5.0 - http://www.lua.org/manual/5.0/manual.html#2.9.2). En d'autres termes le code suivant, qui essaye de
changer une table en table faible en changeant le champ de ses __mode
metatable, est erroné :
getmetatable(t).__mode = 'v '
__mode
champ
défini avant qu'elle soit employée en tant que metatable. Par
conséquent le modèle suivant, qui crée une table vide et puis lui
donne immédiatement un metatable, est correct :
weaktable local = setmetatable({}, {_ _ mode="k"})
Des tables faibles sont souvent employées dans les situations où vous souhaitez annoter des valeurs sans les changer. Par exemple, vous pourriez vouloir donner à des objets un nom qui pourrait être employé quand ils ont été imprimés. Dans ce cas-ci, vous ne voudriez pas le fait qu'un objet ait été appelé pour l'empêcher d'être des ordures rassemblées, ainsi vous voudriez employer une table avec des clefs faibles (les objets) :
les noms régionaux = le setmetatable({}, {_ _ mode = "k"}) -- avec l'exemple ci-dessous, ce serait un name(obj de fonction de fonction, un streptocoque locaux) names[obj ] = l'extrémité de retour d'obj de tostring(str) -- gardent le print(disponible d'impression de gens du pays de fonction originale d'impression _ = de fonction d'impression...) pour I = 1, arg.n font le nom régional = le names[arg[i ] ] si arg[i de nom puis ] = l'extrémité nommée de print(unpack(arg d'extrémité d'extrémité _))
Vous pourriez vouloir employer ceci pour corriger, en appelant automatiquement des variables globales. Vous pouvez faire ceci en ajoutant un metamethod simple (voir le MetamethodsTutorial) à la table de globals :
globalsmeta local = {} nameable_type local = {[ "fonction" ] = vrai, l'userdata = vrai, fil = rectifient, table = rectifient} fonction globalsmeta:__newindex(k, v) si name(v de nameable_type[type(v) ] puis, k) extrémité rawset(art de l'auto-portrait, k, v) setmetatable(_G d'extrémité, globalsmeta)
Note comment nous évitons de faire une série
complexe if then elseif...
de rapports en employant une table constante
pour faire un contrôle simple sur le type de la valeur.
Pour les lecteurs d'instruction avançés, le texte de la fonction de newindex de __ pourrait être écrit comme suit :
rawset(art de l'auto-portrait, k, (nameable_type[type(v) ] et name(v, k)) ou v)
![]() |
|