mam problemy ze zrozumieniem, dlaczego istnieje różnica w zachowaniu się __index
metamethod między tych przykładów:Lua Metatable Niespójność
A = { __index = A }
function A:speak()
print("I'm an A")
end
An_A = setmetatable({},A)
An_A:speak()
podniesie się następujący błąd: lua: l.lua:8: attempt to call method 'speak' (a nil value)
podczas
B = { __index = function(t,key) return B[key] end }
function B:speak()
print("I'm an B")
end
An_B = setmetatable({},B)
An_B:speak()
Wykona się zgodnie z oczekiwaniami, wyprowadzając I'm an B
.
Próbując zrozumieć, dlaczego miało to czytam this odcinek pil. Stwierdza ona, że:
The use of the __index metamethod for inheritance is so common that Lua provides a shortcut. Despite the name, the __index metamethod does not need to be a function: It can be a table, instead. When it is a function, Lua calls it with the table and the absent key as its arguments. When it is a table, Lua redoes the access in that table.
Moje zrozumienie tego jest, że we fragmencie z udziałem „a”, __index = A
powodować dostępu do zrobienia w tabeli A
(zgodnie z boldened segmenet wyżej cytat). W takim przypadku nie rozumiem, dlaczego funkcja związana z kluczem "speak"
nie została znaleziona. Próbując to naprawić, postanowiłem zaimplementować podejście funkcji w kodzie B
, które zwraca wartość związaną z key
w B
i zadziałało. Z pewnością __index = A
i (dostosowany od B
) __index = function(t,key) return A[key] end
mają taki sam efekt.
Wszelkie wyjaśnienia byłyby bardzo mile widziane.
Dziękuję za wielkie wyjaśnienie, nie przyszło mi do głowy, że to się stanie, założyłem, że będzie to jak inne języki, w których coś takiego jak 'f = lambda n: f (n) 'jest poprawna. Pozdrawiam :) – HennyH
@HennyH: 'f = function (n) return f (n) end' jest w porządku w lua z tego samego powodu. Odpowiednikiem pytającego błędu jest 'd = {" __indeks ": d}', ale python będzie "NameError' – Eric
@Eric Przypuszczam, że każda funkcja rekurencyjna podąża za tym samym wzorcem. – HennyH