⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 manual.html

📁 一种小型的脚本开发语言Lua,Lua参考手册,中文的资料.
💻 HTML
📖 第 1 页 / 共 5 页
字号:
<PRE>
  x = 10                -- global variable
  do                    -- new block
    local x = x         -- new `x', with value 10
    print(x)            --> 10
    x = x+1
    do                  -- another block
      local x = x+1     -- another `x'
      print(x)          --> 12
    end
    print(x)            --> 11
  end
  print(x)              --> 10  (the global one)
</PRE>
Notice that, in a declaration like <code>local x = x</code>,
the new <code>x</code> being declared is not in scope yet,
and so the second <code>x</code> refers to the outside variable.

<p>Because of the lexical scoping rules,
local variables can be freely accessed by functions
defined inside their scope.
For instance:
<PRE>
  local counter = 0
  function inc (x)
    counter = counter + x
    return counter
  end
</PRE>
A local variable used by an inner function is called
an <em>upvalue</em>, or <em>external local variable</em>,
inside the inner function.

<p>Notice that each execution of a <b>local</b> statement
defines new local variables.
Consider the following example:
<PRE>
  a = {}
  local x = 20
  for i=1,10 do
    local y = 0
    a[i] = function () y=y+1; return x+y end
  end
</PRE>
The loop creates ten closures
(that is, ten instances of the anonymous function).
Each of these closures uses a different <code>y</code> variable,
while all of them share the same <code>x</code>.

<p><a name="error"><h2>2.7 - Error Handling</h2></a>

<p>Because Lua is an extension language,
all Lua actions start from C&nbsp;code in the host program
calling a function from the Lua library (see <a href="#lua_pcall">3.15</a>).
Whenever an error occurs during Lua compilation or execution,
control returns to C,
which can take appropriate measures
(such as print an error message).

<p>Lua code can explicitly generate an error by calling the
<code>error</code> function (see <a href="#pdf-error">5.1</a>).
If you need to catch errors in Lua,
you can use the <code>pcall</code> function (see <a href="#pdf-pcall">5.1</a>).

<p><a name="metatable"><h2>2.8 - Metatables</h2></a>

<p>Every table and userdata object in Lua may have a <em>metatable</em>.
This <em>metatable</em> is an ordinary Lua table
that defines the behavior of the original table and userdata
under certain special operations.
You can change several aspects of the behavior
of an object by setting specific fields in its metatable.
For instance, when an object is the operand of an addition,
Lua checks for a function in the field <code>"__add"</code> in its metatable.
If it finds one,
Lua calls that function to perform the addition.

<p>We call the keys in a metatable <em>events</em>
and the values <em>metamethods</em>.
In the previous example, the event is <code>"add"</code> 
and the metamethod is the function that performs the addition.

<p>You can query and change the metatable of an object
through the <code>set/getmetatable</code>
functions (see <a href="#pdf-getmetatable">5.1</a>).

<p>A metatable may control how an object behaves in arithmetic operations,
order comparisons, concatenation, and indexing.
A metatable can also define a function to be called when a userdata
is garbage collected.
For each of those operations Lua associates a specific key
called an <em>event</em>.
When Lua performs one of those operations over a table or a userdata,
it checks whether that object has a metatable with the corresponding event.
If so, the value associated with that key (the <em>metamethod</em>)
controls how Lua will perform the operation.

<p>Metatables control the operations listed next.
Each operation is identified by its corresponding name.
The key for each operation is a string with its name prefixed by
two underscores;
for instance, the key for operation "add" is the
string <code>"__add"</code>.
The semantics of these operations is better explained by a Lua function
describing how the interpreter executes that operation.

<p>The code shown here in Lua is only illustrative;
the real behavior is hard coded in the interpreter
and it is much more efficient than this simulation.
All functions used in these descriptions
(<code>rawget</code>, <code>tonumber</code>, etc.)
are described in <a href="#predefined">5.1</a>.
In particular, to retrieve the metamethod of a given object,
we use the expression
<PRE>
  metatable(obj)[event]
</PRE>
This should be read as
<PRE>
  rawget(metatable(obj) or {}, event)
</PRE>
That is, the access to a metamethod does not invoke other metamethods,
and the access to objects with no metatables does not fail
(it simply results in <B>nil</B>).

<p><ul>

<p><li><b>"add":</b>
the <code>+</code> operation.

<p>The function <code>getbinhandler</code> below defines how Lua chooses a handler
for a binary operation.
First, Lua tries the first operand.
If its type does not define a handler for the operation,
then Lua tries the second operand.
<PRE>
 function getbinhandler (op1, op2, event)
   return metatable(op1)[event] or metatable(op2)[event]
 end
</PRE>
Using that function,
the behavior of the <code>op1 + op2</code> is
<PRE>
 function add_event (op1, op2)
   local o1, o2 = tonumber(op1), tonumber(op2)
   if o1 and o2 then  -- both operands are numeric?
     return o1 + o2   -- `+' here is the primitive `add'
   else  -- at least one of the operands is not numeric
     local h = getbinhandler(op1, op2, "__add")
     if h then
       -- call the handler with both operands
       return h(op1, op2)
     else  -- no handler available: default behavior
       error("...")
     end
   end
 end
</PRE>

<p><li><b>"sub":</b>
the <code>-</code> operation.
Behavior similar to the "add" operation.

<p><li><b>"mul":</b>
the <code>*</code> operation.
Behavior similar to the "add" operation.

<p><li><b>"div":</b>
the <code>/</code> operation.
Behavior similar to the "add" operation.

<p><li><b>"pow":</b>
the <code>^</code> (exponentiation) operation.
<PRE>
 function pow_event (op1, op2)
   local o1, o2 = tonumber(op1), tonumber(op2)
   if o1 and o2 then  -- both operands are numeric?
     return __pow(o1, o2)   -- call global `__pow'
   else  -- at least one of the operands is not numeric
     local h = getbinhandler(op1, op2, "__pow")
     if h then
       -- call the handler with both operands
       return h(op1, op2)
     else  -- no handler available: default behavior
       error("...")
     end
   end
  end
</PRE>

<p><li><b>"unm":</b>
the unary <code>-</code> operation.
<PRE>
 function unm_event (op)
   local o = tonumber(op)
   if o then  -- operand is numeric?
     return -o  -- `-' here is the primitive `unm'
   else  -- the operand is not numeric.
     -- Try to get a handler from the operand
     local h = metatable(op).__unm
     if h then
       -- call the handler with the operand and nil
       return h(op, nil)
     else  -- no handler available: default behavior
       error("...")
     end
   end
 end
</PRE>

<p><li><b>"concat":</b>
the <code>..</code> (concatenation) operation.
<PRE>
 function concat_event (op1, op2)
   if (type(op1) == "string" or type(op1) == "number") and
      (type(op2) == "string" or type(op2) == "number") then
     return op1 .. op2  -- primitive string concatenation
   else
     local h = getbinhandler(op1, op2, "__concat")
     if h then
       return h(op1, op2)
     else
       error("...")
     end
   end
 end
</PRE>

<p><li><b>"eq":</b>
the <code>==</code> operation.
The function <code>getcomphandler</code> defines how Lua chooses a metamethod
for comparison operators.
A metamethod only is selected when both objects
being compared have the same type
and the same metamethod for the selected operation.
<PRE>
 function getcomphandler (op1, op2, event)
   if type(op1) ~= type(op2) then return nil end
   local mm1 = metatable(op1)[event]
   local mm2 = metatable(op2)[event]
   if mm1 == mm2 then return mm1 else return nil end
 end
</PRE>
The "eq" event is defined as follows:
<PRE>
 function eq_event (op1, op2)
   if type(op1) ~= type(op2) then  -- diferent types?
     return false   -- different objects
   end
   if op1 == op2 then   -- primitive equal?
     return true   -- objects are equal
   end
   -- try metamethod
   local h = getcomphandler(op1, op2, "__eq")
   if h then
     return h(op1, op2)
   else
     return false
   end
 end
</PRE>
<code>a ~= b</code> is equivalent to <code>not (a == b)</code>.

<p><li><b>"lt":</b>
the <code>&#060;</code> operation.
<PRE>
 function lt_event (op1, op2)
   if type(op1) == "number" and type(op2) == "number" then
     return op1 &#060; op2   -- numeric comparison
   elseif type(op1) == "string" and type(op2) == "string" then
     return op1 &#060; op2   -- lexicographic comparison
   else
     local h = getcomphandler(op1, op2, "__lt")
     if h then
       return h(op1, op2)
     else
       error("...");
     end
   end
 end
</PRE>
<code>a > b</code> is equivalent to <code>b &#060; a</code>.

<p><li><b>"le":</b>
the <code>&#060;=</code> operation.
<PRE>
 function le_event (op1, op2)
   if type(op1) == "number" and type(op2) == "number" then
     return op1 &#060;= op2   -- numeric comparison
   elseif type(op1) == "string" and type(op2) == "string" then
     return op1 &#060;= op2   -- lexicographic comparison
   else
     local h = getcomphandler(op1, op2, "__le")
     if h then
       return h(op1, op2)
     else
       h = getcomphandler(op1, op2, "__lt")
       if h then
         return not h(op2, op1)
       else
         error("...");
       end
     end
   end
 end
</PRE>
<code>a >= b</code> is equivalent to <code>b &#060;= a</code>.
Note that, in the absence of a "le" metamethod,
Lua tries the "lt", assuming that <code>a &#060;= b</code> is
equivalent to <code>not (b &#060; a)</code>.

<p><li><b>"index":</b>
The indexing access <code>table[key]</code>.
<PRE>
 function gettable_event (table, key)
   local h
   if type(table) == "table" then
     local v = rawget(table, key)
     if v ~= nil then return v end
     h = metatable(table).__index
     if h == nil then return nil end
   else
     h = metatable(table).__index
     if h == nil then
       error("...");
     end
   end
   if type(h) == "function" then
     return h(table, key)      -- call the handler
   else return h[key]          -- or repeat operation on it
 end
</PRE>

<p><li><b>"newindex":</b>
The indexing assignment <code>table[key] = value</code>.
<PRE>
 function settable_event (table, key, value)
   local h
   if type(table) == "table" then
     local v = rawget(table, key)
     if v ~= nil then rawset(table, key, value); return end
     h = metatable(table).__newindex
     if h == nil then rawset(table, key, value); return end
   else
     h = metatable(table).__newindex
     if h == nil then
       error("...");
     end
   end
   if type(h) == "function" then
     return h(table, key,value)    -- call the handler
   else h[key] = value             -- or repeat operation on it
 end
</PRE>

<p><li><b>"call":</b>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -