2015-03-17 9 views
8

Jestem świadomy słabej funkcjonalności tabel w Lua, jednak chciałbym mieć słabe odniesienie z jedną zmienną.Słaba referencja Lua

Widziałem this proposal co sugeruje API następująco:

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

które wydają się idealne. Jednak wydaje się, że nie ma to miejsca w dokumentacji w innym miejscu; tylko słabe tabele.

Czy istnieje coś podobnego do funkcji Pythona w wersji weak reference to object?

+1

Co ostatecznie próbujesz zrobić tutaj? Możesz naśladować to samemu, używając tabeli z metatable, w którą wierzę (lub z 'newproxy' i metatable), jeśli naprawdę potrzebujesz. –

+0

Używam middleclass dla OO, przekazując zamknięcie z objA na objB. Kiedy objA wychodzi poza zasięg, zamknięcie uniemożliwia obu GC'd instancji, ponieważ zawiera odniesienie do objA. Nigdy wcześniej nie słyszałem o nowym proxy, idąc do google ... – MarkNS

+0

hmmm .. "Nieudokumentowana funkcja newproxy została usunięta w Lua 5.2, ponieważ została ona nadmiarowa dzięki innym funkcjom dodanym w tej wersji" od http: // lua-users .org/wiki/HiddenFeatures – MarkNS

Odpowiedz

4

Coś takiego może zrobić to, co chcesz mi wierzyć:

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()) 

The __call udział jest opcjonalny, ale zapewnia składnię wywołania ref(). Bez niego musisz użyć wersji z bezpośrednim dostępem.

7

Kiedy lua czegoś nie dostarcza, często istnieje prosty sposób implementacji go z innych prymitywów.

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

Tworzymy słabą tabelę z danymi w niej zawartymi. Następnie zwracamy funkcję, która po wywołaniu zwraca zawartość tej tabeli.

(Uwaga, słabe referencje nie mogą być złamane aż zbierania śmieci i literały nigdy nie są śmieci zebrane.)

+0

Szkoda, że ​​ta odpowiedź nie została zaakceptowana - jest lepsza niż zaakceptowana, I przyszła o minutę wcześniej. – fluffy

+1

Inna odpowiedź ma kilka bardzo ważnych rzeczy idących na to ... w szczególności, ma potencjał, aby utworzyć mniej śmieci, ponieważ moje rozwiązanie tworzy obiekt i zamknięcie tego obiektu dla każdego połączenia, podczas gdy akceptowane rozwiązanie tworzy tylko tabelę . (Oba również fałszywie tworzą nowy metatabel za każdym razem, ale to można wyciągnąć i ponownie wykorzystać). – kazagistar

+0

Ah, dobre punkty. Głównie po prostu potrzebowałem dowiedzieć się o '__mode =" v "' - w moim przypadku użycia robię pulę obrazów i po prostu chciałem słabej tabeli, w której wszystkie wartości w tabeli były możliwe do zebrania. – fluffy