2015-03-17 13 views
8

Ich bin bewusst, die schwachen Tabellen Funktionalität in Lua, aber ich möchte eine schwache Referenz mit einer einzigen Variable haben.Lua schwache Referenz

Ich habe this proposal gesehen, die eine API schlägt vor, wie folgt:

-- creation 
ref = weakref(obj) 
-- dereference 
obj = ref() 

das wäre ideal zu sein scheinen. Dies scheint jedoch an anderer Stelle nicht in der Dokumentation zu sein. nur schwache Tabellen.

Gibt es etwas analog zu Pythons weak reference to object Funktionalität?

+1

Was versuchen Sie hier letztlich zu tun? Sie können dies selbst nachbilden, indem Sie eine Tabelle mit atmetable verwenden, die ich glaube (oder mit 'newproxy' und einer Metatabelle), wenn Sie wirklich brauchen. –

+0

Ich benutze Mittelklasse für OO, eine Schließung von ObjA zu ObjB übergeben. Wenn objA den Gültigkeitsbereich verlässt, verhindert die Schließung, dass beide Instanzen erfasst werden, da es einen Verweis auf objA enthält. Hab noch nie von newproxy gehört, google es ... – MarkNS

+0

hmmm .. "Die undokumentierte newproxy-Funktion wurde in Lua 5.2 entfernt, da sie durch andere in dieser Version hinzugefügte Funktionen überflüssig gemacht wurde" von http: // lua-users .org/wiki/HiddenFeatures – MarkNS

Antwort

4

So etwas kann tun, was Sie wollen, ich glaube:

local obj = {value = "obj.value"} 

local ref = setmetatable({real = obj}, {__mode = "v", __call = function(self) return self.real end}) 

print(obj.value) 
print(ref.real.value) 
print(ref().value) 

obj = nil 
collectgarbage() 
collectgarbage() 

print(obj) 
print(ref.real) 
print(ref()) 

Der __call Teil ist optional, gibt Ihnen aber die ref() Aufrufsyntax. Ohne es müssen Sie die Direct-Access-Version verwenden.

7

Wenn Lua nichts bietet, gibt es oft einen einfachen Weg, es von den anderen Primitiven zu implementieren.

function weakref(data) 
    local weak = setmetatable({content=data}, {__mode="v"}) 
    return function() return weak.content end 
end 

Wir erstellen eine schwache Tabelle mit nur den Daten darin. Dann geben wir eine Funktion zurück, die beim Aufruf den Inhalt dieser Tabelle zurückgibt.

(Anmerkung, schwache Referenzen können nicht bis Garbage Collection aufgebrochen werden, und Literale werden nie Müll gesammelt.)

+0

Es ist eine Schande, dass diese Antwort nicht akzeptiert wurde - es ist besser als die angenommene, UND kam etwa eine Minute früher. – fluffy

+1

Die andere Antwort hat einige ziemlich wichtige Dinge für sie ... insbesondere hat sie das Potenzial, weniger Müll zu erzeugen, da meine Lösung für jeden Aufruf ein Objekt und eine Schließung über diesem Objekt erstellt, während die akzeptierte Lösung nur die Tabelle erstellt . (Beide erzeugen auch jedes Mal fälschlicherweise eine neue Metatabelle, aber das könnte herausgezogen und wiederverwendet werden). – kazagistar

+0

Ah, gute Punkte. Meistens musste ich nur etwas über '__mode =" v "' lernen - in meinem Anwendungsfall mache ich einen Bild-Pool und wollte nur eine schwache Tabelle, in der alle Werte in einer Tabelle sammelbar sind. – fluffy