开发者

Some question about "Closure" in Lua

Here's my code, I confuse the local variable 'count' in the return function(c1,c2) with memory strack and where does they store in?

function make_counter()
  local count = 0
  return function()
    count = count + 1
    return count
  end
end
c1 = make_counter()
c2 = make_counter()
print(c1开发者_开发问答())--print->1
print(c1())--print->2
print(c1())--print->3

print(c2())--print->1
print(c2())--print->2


in the return function(c1,c2) with memory strack and where does they store in?

It's stored in the closure!

c1 is not a closure, it is the function returned by make_counter(). The closure is not explicitly declared anywhere. It is the combination of the function returned by make_counter() and the "free variables" of that function. See closures @ Wikipedia, specifically the implementation:

Closures are typically implemented with a special data structure that contains a pointer to the function code, plus a representation of the function's lexical environment (e.g., the set of available variables and their values) at the time when the closure was created.


I'm not quite sure what you're asking exactly, but I'll try to explain how closures work.

When you do this in Lua:

function() <some Lua code> end

You are creating a value. Values are things like the number 1, the string "string", and so forth.

Values are immutable. For example, the number 1 is always the number 1. It can never be the number two. You can add 1 to 2, but that will give you a new number 3. The same goes for strings. The string "string" is a string and will always be that particular string. You can use Lua functions to take away all 'g' characters in the string, but this will create a new string "strin".

Functions are values, just like the number 1 and the string "string". Values can be stored in variables. You can store the number 1 in multiple variables. You can store the string "string" in multiple variables. And the same goes for all other kinds of values, including functions.

Functions are values, and therefore they are immutable. However, functions can contain values; these values are not immutable. It's much like tables.

The {} syntax creates a Lua table, which is a value. This table is different from every other table, even other empty tables. However, you can put different stuff in tables. This doesn't change the unique value of the table, but it does change what is stored within that table. Each time you execute {}, you get a new, unique table. So if you have the following function:

function CreateTable()
    return {}
end

The following will be true:

tableA = CreateTable()
tableB = CreateTable()
if(tableA == tableB) then
    print("You will never see this")
else
    print("Always printed")
end

Even though both tableA and tableB are empty tables (contain the same thing), they are different tables. They may contain the same stuff, but they are different values.

The same goes for functions. Functions in Lua are often called "closures", particularly if the function has contents. Functions are given contents based on how they use variables. If a function references a local variable that is in scope at the location where that function is created (remember: the syntax function() end creates a function every time you call it), then the function will contain a reference to that local variable.

But local variables go out of scope, while the value of the function may live on (in your case, you return it). Therefore, the function's object, the closure, must contain a reference to that local variable that will cause it to continue existing until the closure itself is discarded.

Where do the values get stored? It doesn't matter; only the closure can access them (though there is a way through the C Lua API, or through the Lua Debug API). So unlike tables, where you can get at anything you want, closures can truly hide data.


Lua Closures can also be used to implement prototype-based classes and objects. Closure classes and objects behave slightly differently than normal Lua classes and their method of invocation is somewhat different:

-- closure class definition

StarShip = {}

function StarShip.new(x,y,z)
    self = {}

    local dx, dy, dz
    local curx, cury, curz
    local engine_warpnew

    cur_x = x; cur_y = y; cur_z = z

    function setDest(x,y,z)
        dx = x; dy=y; dz=z;
    end

    function setSpeed(warp)
        engine_warpnew = warp
    end

    function self.warp(x,y,z,speed)
        print("warping to ",x,y,x," at warp ",speed)
        setDest(x,y,z)
        setSpeed(speed)
    end

    function self.currlocation()
        return {x=cur_x, y=cur_y, z=cur_z}
    end

    return self
end

enterprise = StarShip.new(1,3,9)

enterprise.warp(0,0,0,10)

loc = enterprise.currlocation()

print(loc.x, loc.y, loc.z)

Produces the following output:

warping to 0 0 0 at warp 10 1 3 9

Here we define a prototype object "StarShip" as an empty table.

Then we create a constructor for the StarShip in the "new" method. The first thing it does is create a closure table called self that contains the object's methods. All methods in the closure (those defined as 'function self.') are "closed" or defined for all values accessible by the constructor. This is why it's called a closure. When the constructor is done it returns the closure object "return self".

A lot more information on closure-based objects is available here:

http://lua-users.org/wiki/ObjectOrientationClosureApproach

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜