2017-01-22 7 views
3

Ich habe diesen Code nicht ein Prototyp ist:Warum ist es die gleiche Tabelle, obwohl es

function createRect(x, y, w, h) 
    local rect = { 
    type = "rect", 
    x = x, 
    y = y, 
    w = w, 
    h = h, 
    translate = function(rect, vector) 
     assert(vector.type == "vector2d") 
     local rect = shapes.createRect(rect.x + vector.x, rect.y + vector.y, rect.w, rect.h) 
    end, 
    } 

    return rect 
end 

translate = function(rect, vector) 
    assert(vector.type == "vector2d") 
    local rect = shapes.createRect(rect.x + vector.x, rect.y + vector.y, rect.w, rect.h) 
end 

local o = createRect(2,3,4,5) 
local q = createRect(2,3,4,5) 

print(o.translate, q.translate, translate) 

die einige sehr einfache Code und ist in Lua zu Testfactory Funktionen geschrieben und erinnert sehr an die JS Modulmuster. Etwas, worüber sich Leute normalerweise beschweren, wenn sie über Fabrikfunktionen sprechen, ist der Speicherbedarf. Da o und q nur zugewiesen sind, haben sie natürlich unterschiedliche Funktionen, vermutete ich. Ich war jedoch als falsch erwiesen:

function: 0x7fcdbe600d50  function: 0x7fcdbe600d50  function: 0x7fcdbe600d90 

Warum ist das? Wie kann das überhaupt sein? Ich nahm o.translate und q.translate werden verschiedene Funktionen sein, aber sie sind die gleichen ...

Antwort

5

Wie kann das gerade? Ich nahm o.translate und q.translate werden verschiedene Funktionen sein, aber sie sind die gleichen ...

Normalerweise sind Sie richtig, aber Lua 5.2 eine Optimierung eingeführt, wo anonyme Funktionen im Cache gespeichert werden können, wenn bestimmte Bedingungen erfüllt sind. Wenn die Werte, auf die es verweist, zwischen der Konstruktion nicht geändert werden, wird die zuerst erstellte Instanz dieser anonymen Funktion erneut verwendet.

Laufen Ihr Beispiel in repl.it, Lua 5.1, zeigt dies als eine mögliche Ausgabe:

function: 0xb81f30 function: 0xb81f00 function: 0xb82ca0 

Aber es unter melpon.org/wandbox läuft, Lua 5.2+, zeigt:

function: 0x14f0650 function: 0x14f0650 function: 0x14efb40 

In Ihrem Beispiel createRect erstellt und gibt eine andere rect Tabelle für jeden Aufruf zurück, aber das Feld rect.translate erhält aufgrund dieser Optimierung die gleiche anonyme Funktion wie der Lua-Wert.

Siehe auch

Verwandte Themen