﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-每天早晨叫醒你的不是闹钟,而是梦想-随笔分类-Script</title><link>http://www.cppblog.com/mmdengwo/category/20811.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 17 Feb 2014 11:36:36 GMT</lastBuildDate><pubDate>Mon, 17 Feb 2014 11:36:36 GMT</pubDate><ttl>60</ttl><item><title>Step By Step(userdata)</title><link>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205809.html</link><dc:creator>沛沛</dc:creator><author>沛沛</author><pubDate>Mon, 17 Feb 2014 09:50:00 GMT</pubDate><guid>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205809.html</guid><wfw:comment>http://www.cppblog.com/mmdengwo/comments/205809.html</wfw:comment><comments>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205809.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mmdengwo/comments/commentRss/205809.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mmdengwo/services/trackbacks/205809.html</trackback:ping><description><![CDATA[<p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp; &nbsp;在Lua中可以通过自定义类型的方式与C语言代码更高效、更灵活的交互。这里我们通过一个简单完整的示例来学习一下Lua中userdata的使用方式。需要说明的是，该示例完全来自于Programming in Lua。其功能是用C程序实现一个Lua的布尔数组，以提供程序的执行效率。见下面的代码和关键性注释。 &nbsp;&nbsp;</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">  1</span> #include &lt;lua.hpp&gt; <span style="color: #008080; line-height: 1.5 !important;">  <br />  2</span> #include &lt;lauxlib.h&gt; <span style="color: #008080; line-height: 1.5 !important;">  <br />  3</span> #include &lt;lualib.h&gt; <span style="color: #008080; line-height: 1.5 !important;">  <br />  4</span> #include &lt;limits.h&gt; <span style="color: #008080; line-height: 1.5 !important;">  <br />  5</span>  <span style="color: #008080; line-height: 1.5 !important;">  <br />  6</span> <span style="color: #0000ff; line-height: 1.5 !important;">#define</span> BITS_PER_WORD (CHAR_BIT * sizeof(int)) <span style="color: #008080; line-height: 1.5 !important;">  <br />  7</span> <span style="color: #0000ff; line-height: 1.5 !important;">#define</span> I_WORD(i)     ((unsigned int)(i))/BITS_PER_WORD <span style="color: #008080; line-height: 1.5 !important;">  <br />  8</span> <span style="color: #0000ff; line-height: 1.5 !important;">#define</span> I_BIT(i)      (1 &lt;&lt; ((unsigned int)(i)%BITS_PER_WORD)) <span style="color: #008080; line-height: 1.5 !important;">  <br />  9</span>  <span style="color: #008080; line-height: 1.5 !important;"> <br />  10</span> typedef <span style="color: #0000ff; line-height: 1.5 !important;">struct</span><span style="line-height: 1.5 !important;"> NumArray { </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  11</span>     <span style="color: #0000ff; line-height: 1.5 !important;">int</span><span style="line-height: 1.5 !important;"> size; </span><span style="color: #008080; line-height: 1.5 !important;"> 12</span>     unsigned <span style="color: #0000ff; line-height: 1.5 !important;">int</span> values[<span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">]; </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  13</span> <span style="line-height: 1.5 !important;">} NumArray; </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  14</span>  <span style="color: #008080; line-height: 1.5 !important;"> <br />  15</span> <span style="color: #0000ff; line-height: 1.5 !important;">extern</span> <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">C</span><span style="color: #800000; line-height: 1.5 !important;">"</span> <span style="color: #0000ff; line-height: 1.5 !important;">int</span> newArray(lua_State*<span style="line-height: 1.5 !important;"> L) </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  16</span> <span style="line-height: 1.5 !important;">{ </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  17</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">1. 检查第一个参数是否为整型。以及该参数的值是否大于等于1.</span> <span style="color: #008080; line-height: 1.5 !important;"> <br />  18</span>     <span style="color: #0000ff; line-height: 1.5 !important;">int</span> n = luaL_checkint(L,<span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  19</span>     luaL_argcheck(L, n &gt;= <span style="color: #800080; line-height: 1.5 !important;">1</span>, <span style="color: #800080; line-height: 1.5 !important;">1</span>, <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">invalid size.</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  20</span>     size_t nbytes = <span style="color: #0000ff; line-height: 1.5 !important;">sizeof</span>(NumArray) + I_WORD(n - <span style="color: #800080; line-height: 1.5 !important;">1</span>) * <span style="color: #0000ff; line-height: 1.5 !important;">sizeof</span>(<span style="color: #0000ff; line-height: 1.5 !important;">int</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  21</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">2. 参数表示Lua为userdata分配的字节数。同时将分配后的userdata对象压入栈中。</span> <span style="color: #008080; line-height: 1.5 !important;"> <br />  22</span>     NumArray* a = (NumArray*<span style="line-height: 1.5 !important;">)lua_newuserdata(L,nbytes); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  23</span>     a-&gt;size =<span style="line-height: 1.5 !important;"> n; </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  24</span>     <span style="color: #0000ff; line-height: 1.5 !important;">for</span> (<span style="color: #0000ff; line-height: 1.5 !important;">int</span> i = <span style="color: #800080; line-height: 1.5 !important;">0</span>; i &lt; I_WORD(n - <span style="color: #800080; line-height: 1.5 !important;">1</span>); ++<span style="line-height: 1.5 !important;">i) </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  25</span>         a-&gt;values[i] = <span style="color: #800080; line-height: 1.5 !important;">0</span><span style="line-height: 1.5 !important;">; </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  26</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">获取注册表变量myarray，该key的值为metatable。</span> <span style="color: #008080; line-height: 1.5 !important;"> <br />  27</span>     luaL_getmetatable(L,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">myarray</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  28</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">将userdata的元表设置为和myarray关联的table。同时将栈顶元素弹出。</span> <span style="color: #008080; line-height: 1.5 !important;"> <br />  29</span>     lua_setmetatable(L,-<span style="color: #800080; line-height: 1.5 !important;">2</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  30</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">; </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  31</span> <span style="line-height: 1.5 !important;">} </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  32</span>  <span style="color: #008080; line-height: 1.5 !important;"> <br />  33</span> <span style="color: #0000ff; line-height: 1.5 !important;">extern</span> <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">C</span><span style="color: #800000; line-height: 1.5 !important;">"</span> <span style="color: #0000ff; line-height: 1.5 !important;">int</span> setArray(lua_State*<span style="line-height: 1.5 !important;"> L) </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  34</span> <span style="line-height: 1.5 !important;">{ </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  35</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">1. Lua传给该函数的第一个参数必须是userdata，该对象的元表也必须是注册表中和myarray关联的table。 </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  36</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">否则该函数报错并终止程序。</span> <span style="color: #008080; line-height: 1.5 !important;"> <br />  37</span>     NumArray* a = (NumArray*)luaL_checkudata(L,<span style="color: #800080; line-height: 1.5 !important;">1</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">myarray</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  38</span>     <span style="color: #0000ff; line-height: 1.5 !important;">int</span> index = luaL_checkint(L,<span style="color: #800080; line-height: 1.5 !important;">2</span>) - <span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">; </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  39</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">2. 由于任何类型的数据都可以成为布尔值，因此这里使用any只是为了确保有3个参数。</span> <span style="color: #008080; line-height: 1.5 !important;"> <br />  40</span>     luaL_checkany(L,<span style="color: #800080; line-height: 1.5 !important;">3</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  41</span>     luaL_argcheck(L,a != NULL,<span style="color: #800080; line-height: 1.5 !important;">1</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">'array' expected.</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  42</span>     luaL_argcheck(L,<span style="color: #800080; line-height: 1.5 !important;">0</span> &lt;= index &amp;&amp; index &lt; a-&gt;size,<span style="color: #800080; line-height: 1.5 !important;">2</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">index out of range.</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  43</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span> (lua_toboolean(L,<span style="color: #800080; line-height: 1.5 !important;">3</span><span style="line-height: 1.5 !important;">)) </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  44</span>         a-&gt;values[I_WORD(index)] |=<span style="line-height: 1.5 !important;"> I_BIT(index); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  45</span>     <span style="color: #0000ff; line-height: 1.5 !important;">else</span> <span style="color: #008080; line-height: 1.5 !important;"> <br />  46</span>         a-&gt;values[I_WORD(index)] &amp;= ~<span style="line-height: 1.5 !important;">I_BIT(index); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  47</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #800080; line-height: 1.5 !important;">0</span><span style="line-height: 1.5 !important;">; </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  48</span> <span style="line-height: 1.5 !important;">} </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  49</span>  <span style="color: #008080; line-height: 1.5 !important;"> <br />  50</span> <span style="color: #0000ff; line-height: 1.5 !important;">extern</span> <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">C</span><span style="color: #800000; line-height: 1.5 !important;">"</span> <span style="color: #0000ff; line-height: 1.5 !important;">int</span> getArray(lua_State*<span style="line-height: 1.5 !important;"> L) </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  51</span> <span style="line-height: 1.5 !important;">{ </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  52</span>     NumArray* a = (NumArray*)luaL_checkudata(L,<span style="color: #800080; line-height: 1.5 !important;">1</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">myarray</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  53</span>     <span style="color: #0000ff; line-height: 1.5 !important;">int</span> index = luaL_checkint(L,<span style="color: #800080; line-height: 1.5 !important;">2</span>) - <span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">; </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  54</span>     luaL_argcheck(L, a != NULL, <span style="color: #800080; line-height: 1.5 !important;">1</span>, <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">'array' expected.</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  55</span>     luaL_argcheck(L, <span style="color: #800080; line-height: 1.5 !important;">0</span> &lt;= index &amp;&amp; index &lt; a-&gt;size,<span style="color: #800080; line-height: 1.5 !important;">2</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">index out of range</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  56</span>     lua_pushboolean(L,a-&gt;values[I_WORD(index)] &amp;<span style="line-height: 1.5 !important;"> I_BIT(index)); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  57</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">; </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  58</span> <span style="line-height: 1.5 !important;">} </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  59</span>  <span style="color: #008080; line-height: 1.5 !important;"> <br />  60</span> <span style="color: #0000ff; line-height: 1.5 !important;">extern</span> <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">C</span><span style="color: #800000; line-height: 1.5 !important;">"</span> <span style="color: #0000ff; line-height: 1.5 !important;">int</span> getSize(lua_State*<span style="line-height: 1.5 !important;"> L) </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  61</span> <span style="line-height: 1.5 !important;">{ </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  62</span>     NumArray* a = (NumArray*)luaL_checkudata(L,<span style="color: #800080; line-height: 1.5 !important;">1</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">myarray</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  63</span>     luaL_argcheck(L,a != NULL,<span style="color: #800080; line-height: 1.5 !important;">1</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">'array' expected.</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  64</span>     lua_pushinteger(L,a-&gt;<span style="line-height: 1.5 !important;">size); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  65</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">; </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  66</span> <span style="line-height: 1.5 !important;">} </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  67</span>  <span style="color: #008080; line-height: 1.5 !important;"> <br />  68</span> <span style="color: #0000ff; line-height: 1.5 !important;">extern</span> <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">C</span><span style="color: #800000; line-height: 1.5 !important;">"</span> <span style="color: #0000ff; line-height: 1.5 !important;">int</span> array2string(lua_State*<span style="line-height: 1.5 !important;"> L) </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  69</span> <span style="line-height: 1.5 !important;">{ </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  70</span>     NumArray* a = (NumArray*)luaL_checkudata(L,<span style="color: #800080; line-height: 1.5 !important;">1</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">myarray</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  71</span>     lua_pushfstring(L,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">array(%d)</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,a-&gt;<span style="line-height: 1.5 !important;">size); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  72</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">; </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  73</span> <span style="line-height: 1.5 !important;">} </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  74</span>  <span style="color: #008080; line-height: 1.5 !important;"> <br />  75</span> <span style="color: #0000ff; line-height: 1.5 !important;">static</span> luaL_Reg arraylib_f [] =<span style="line-height: 1.5 !important;"> {  </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  76</span>     {<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">new</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">, newArray}, </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  77</span> <span style="line-height: 1.5 !important;">    {NULL, NULL}  </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  78</span> <span style="line-height: 1.5 !important;">};  </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  79</span>  <span style="color: #008080; line-height: 1.5 !important;"> <br />  80</span> <span style="color: #0000ff; line-height: 1.5 !important;">static</span> luaL_Reg arraylib_m [] =<span style="line-height: 1.5 !important;"> { </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  81</span>     {<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">set</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">, setArray}, </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  82</span>     {<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">get</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">, getArray}, </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  83</span>     {<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">size</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">, getSize}, </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  84</span>     {<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">__tostring</span><span style="color: #800000; line-height: 1.5 !important;">"</span>, array2string}, <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">print(a)时Lua会调用该元方法。</span> <span style="color: #008080; line-height: 1.5 !important;"> <br />  85</span> <span style="line-height: 1.5 !important;">    {NULL, NULL}  </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  86</span> <span style="line-height: 1.5 !important;">}; </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  87</span>  <span style="color: #008080; line-height: 1.5 !important;"> <br />  88</span> <span style="color: #0000ff; line-height: 1.5 !important;">extern</span> <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">C</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;"> __declspec(dllexport) </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  89</span> <span style="color: #0000ff; line-height: 1.5 !important;">int</span> luaopen_testuserdata(lua_State*<span style="line-height: 1.5 !important;"> L) </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  90</span> <span style="line-height: 1.5 !important;">{ </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  91</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">1. 创建元表，并将该元表指定给newArray函数新创建的userdata。在Lua中userdata也是以table的身份表现的。 </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  92</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">这样在调用对象函数时，可以通过验证其metatable的名称来确定参数userdata是否合法。</span> <span style="color: #008080; line-height: 1.5 !important;"> <br />  93</span>     luaL_newmetatable(L,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">myarray</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  94</span>     lua_pushvalue(L,-<span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">); <br /></span><span style="color: #008080; line-height: 1.5 !important;">  95</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">2. 为了实现面对对象的调用方式，需要将元表的__index字段指向自身，同时再将arraylib_m数组中的函数注册到 </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  96</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">元表中，之后基于这些注册函数的调用就可以以面向对象的形式调用了。 </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  97</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">lua_setfield在执行后会将栈顶的table弹出。</span> <span style="color: #008080; line-height: 1.5 !important;"> <br />  98</span>     lua_setfield(L,-<span style="color: #800080; line-height: 1.5 !important;">2</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">__index</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  99</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">将这些成员函数注册给元表，以保证Lua在寻找方法时可以定位。NULL参数表示将用栈顶的table代替第二个参数。</span>   <br /><span style="color: #008080; line-height: 1.5 !important;">  100</span> <span style="line-height: 1.5 !important;">   luaL_register(L,NULL,arraylib_m); <br /></span><span style="color: #008080; line-height: 1.5 !important;">  101</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">这里只注册的工厂方法。</span> <br /><span style="color: #008080; line-height: 1.5 !important;">  102</span>     luaL_register(L,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">testuserdata</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">,arraylib_f); <br /></span><span style="color: #008080; line-height: 1.5 !important;">  103</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">; <br /></span><span style="color: #008080; line-height: 1.5 !important;">  104</span> }</pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><span style="color: #800080; font-size: 15px;">　　轻量级userdata：&nbsp;</span><br />　　之前介绍的是full userdata，Lua还提供了另一种轻量级userdata(light userdata)。事实上，轻量级userdata仅仅表示的是C指针的值，即(void*)。由于它只是一个值，所以不用创建。如果需要将一个轻量级userdata放入栈中，调用lua_pushlightuserdata即可。full userdata和light userdata之间最大的区别来自于相等性判断，对于一个full userdata，它只是与自身相等，而light userdata则表示为一个C指针，因此，它与所有表示同一指针的light userdata相等。再有就是light userdata不会受到垃圾收集器的管理，使用时就像一个普通的整型数字一样。</p><img src ="http://www.cppblog.com/mmdengwo/aggbug/205809.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mmdengwo/" target="_blank">沛沛</a> 2014-02-17 17:50 <a href="http://www.cppblog.com/mmdengwo/archive/2014/02/17/205809.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Step By Step(编写C函数的技巧)</title><link>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205808.html</link><dc:creator>沛沛</dc:creator><author>沛沛</author><pubDate>Mon, 17 Feb 2014 09:45:00 GMT</pubDate><guid>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205808.html</guid><wfw:comment>http://www.cppblog.com/mmdengwo/comments/205808.html</wfw:comment><comments>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205808.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mmdengwo/comments/commentRss/205808.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mmdengwo/services/trackbacks/205808.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;1. 数组操作：&nbsp;&nbsp; &nbsp;在Lua中，&#8220;数组&#8221;只是table的一个别名，是指以一种特殊的方法来使用table。出于性能原因，Lua的C API为数组操作提供了专门的函数，如：&nbsp;&nbsp; &nbsp;void lua_rawgeti(lua_State* L, int index, int key);&nbsp;&nbsp...&nbsp;&nbsp;<a href='http://www.cppblog.com/mmdengwo/archive/2014/02/17/205808.html'>阅读全文</a><img src ="http://www.cppblog.com/mmdengwo/aggbug/205808.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mmdengwo/" target="_blank">沛沛</a> 2014-02-17 17:45 <a href="http://www.cppblog.com/mmdengwo/archive/2014/02/17/205808.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Step By Step(Lua调用C函数)</title><link>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205807.html</link><dc:creator>沛沛</dc:creator><author>沛沛</author><pubDate>Mon, 17 Feb 2014 09:45:00 GMT</pubDate><guid>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205807.html</guid><wfw:comment>http://www.cppblog.com/mmdengwo/comments/205807.html</wfw:comment><comments>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205807.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mmdengwo/comments/commentRss/205807.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mmdengwo/services/trackbacks/205807.html</trackback:ping><description><![CDATA[<p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;Lua可以调用C函数的能力将极大的提高Lua的可扩展性和可用性。对于有些和操作系统相关的功能，或者是对效率要求较高的模块，我们完全可以通过C函数来实现，之后再通过Lua调用指定的C函数。对于那些可被Lua调用的C函数而言，其接口必须遵循Lua要求的形式，即<span style="color: #0000ff;">typedef int (*lua_CFunction)(lua_State* L)</span>。简单说明一下，该函数类型仅仅包含一个表示Lua环境的指针作为其唯一的参数，实现者可以通过该指针进一步获取Lua代码中实际传入的参数。返回值是整型，表示该C函数将返回给Lua代码的返回值数量，如果没有返回值，则return 0即可。需要说明的是，C函数无法直接将真正的返回值返回给Lua代码，而是通过虚拟栈来传递Lua代码和C函数之间的调用参数和返回值的。这里我们将介绍两种Lua调用C函数的规则。<br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp; &nbsp;1. C函数作为应用程序的一部分。</span></p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> #include &lt;stdio.h&gt; <span style="color: #008080; line-height: 1.5 !important;"> <br />2</span> #include &lt;<span style="color: #0000ff; line-height: 1.5 !important;">string</span>.h&gt; <span style="color: #008080; line-height: 1.5 !important;"> <br />3</span> #include &lt;lua.hpp&gt; <span style="color: #008080; line-height: 1.5 !important;"> <br />4</span> #include &lt;lauxlib.h&gt; <span style="color: #008080; line-height: 1.5 !important;"> <br />5</span> #include &lt;lualib.h&gt; <span style="color: #008080; line-height: 1.5 !important;"> <br />6</span>  <span style="color: #008080; line-height: 1.5 !important;"> <br />7</span> <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">待Lua调用的C注册函数。</span> <span style="color: #008080; line-height: 1.5 !important;"> <br />8</span> <span style="color: #0000ff; line-height: 1.5 !important;">static</span> <span style="color: #0000ff; line-height: 1.5 !important;">int</span> add2(lua_State*<span style="line-height: 1.5 !important;"> L) </span><span style="color: #008080; line-height: 1.5 !important;"> <br />9</span> <span style="line-height: 1.5 !important;">{ <br /></span><span style="color: #008080; line-height: 1.5 !important;">10</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">检查栈中的参数是否合法，1表示Lua调用时的第一个参数(从左到右)，依此类推。 <br /></span><span style="color: #008080; line-height: 1.5 !important;">11</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">如果Lua代码在调用时传递的参数不为number，该函数将报错并终止程序的执行。</span> <br /><span style="color: #008080; line-height: 1.5 !important;">12</span>     <span style="color: #0000ff; line-height: 1.5 !important;">double</span> op1 = luaL_checknumber(L,<span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">); <br /></span><span style="color: #008080; line-height: 1.5 !important;">13</span>     <span style="color: #0000ff; line-height: 1.5 !important;">double</span> op2 = luaL_checknumber(L,<span style="color: #800080; line-height: 1.5 !important;">2</span><span style="line-height: 1.5 !important;">); <br /></span><span style="color: #008080; line-height: 1.5 !important;">14</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">将函数的结果压入栈中。如果有多个返回值，可以在这里多次压入栈中。</span> <br /><span style="color: #008080; line-height: 1.5 !important;">15</span>     lua_pushnumber(L,op1 +<span style="line-height: 1.5 !important;"> op2); <br /></span><span style="color: #008080; line-height: 1.5 !important;">16</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">返回值用于提示该C函数的返回值数量，即压入栈中的返回值数量。</span> <br /><span style="color: #008080; line-height: 1.5 !important;">17</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">; <br /></span><span style="color: #008080; line-height: 1.5 !important;">18</span> <span style="line-height: 1.5 !important;">} <br /></span><span style="color: #008080; line-height: 1.5 !important;">19</span>  <br /><span style="color: #008080; line-height: 1.5 !important;">20</span> <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">另一个待Lua调用的C注册函数。</span> <br /><span style="color: #008080; line-height: 1.5 !important;">21</span> <span style="color: #0000ff; line-height: 1.5 !important;">static</span> <span style="color: #0000ff; line-height: 1.5 !important;">int</span> sub2(lua_State*<span style="line-height: 1.5 !important;"> L) <br /></span><span style="color: #008080; line-height: 1.5 !important;">22</span> <span style="line-height: 1.5 !important;">{ <br /></span><span style="color: #008080; line-height: 1.5 !important;">23</span>     <span style="color: #0000ff; line-height: 1.5 !important;">double</span> op1 = luaL_checknumber(L,<span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">); <br /></span><span style="color: #008080; line-height: 1.5 !important;">24</span>     <span style="color: #0000ff; line-height: 1.5 !important;">double</span> op2 = luaL_checknumber(L,<span style="color: #800080; line-height: 1.5 !important;">2</span><span style="line-height: 1.5 !important;">); <br /></span><span style="color: #008080; line-height: 1.5 !important;">25</span>     lua_pushnumber(L,op1 -<span style="line-height: 1.5 !important;"> op2); <br /></span><span style="color: #008080; line-height: 1.5 !important;">26</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">; <br /></span><span style="color: #008080; line-height: 1.5 !important;">27</span> <span style="line-height: 1.5 !important;">} <br /></span><span style="color: #008080; line-height: 1.5 !important;">28</span>  <br /><span style="color: #008080; line-height: 1.5 !important;">29</span> <span style="color: #0000ff; line-height: 1.5 !important;">const</span> <span style="color: #0000ff; line-height: 1.5 !important;">char</span>* testfunc = <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">print(add2(1.0,2.0)) print(sub2(20.1,19))</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">; <br /></span><span style="color: #008080; line-height: 1.5 !important;">30</span>  <br /><span style="color: #008080; line-height: 1.5 !important;">31</span> <span style="color: #0000ff; line-height: 1.5 !important;">int</span><span style="line-height: 1.5 !important;"> main() <br /></span><span style="color: #008080; line-height: 1.5 !important;">32</span> <span style="line-height: 1.5 !important;">{ <br /></span><span style="color: #008080; line-height: 1.5 !important;">33</span>     lua_State* L =<span style="line-height: 1.5 !important;"> luaL_newstate(); <br /></span><span style="color: #008080; line-height: 1.5 !important;">34</span> <span style="line-height: 1.5 !important;">    luaL_openlibs(L); <br /></span><span style="color: #008080; line-height: 1.5 !important;">35</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">将指定的函数注册为Lua的全局函数变量，其中第一个字符串参数为Lua代码 <br /></span><span style="color: #008080; line-height: 1.5 !important;">36</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">在调用C函数时使用的全局函数名，第二个参数为实际C函数的指针。</span> <br /><span style="color: #008080; line-height: 1.5 !important;">37</span>     lua_register(L, <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">add2</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">, add2); <br /></span><span style="color: #008080; line-height: 1.5 !important;">38</span>     lua_register(L, <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">sub2</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">, sub2); <br /></span><span style="color: #008080; line-height: 1.5 !important;">39</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">在注册完所有的C函数之后，即可在Lua的代码块中使用这些已经注册的C函数了。</span> <br /><span style="color: #008080; line-height: 1.5 !important;">40</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span><span style="line-height: 1.5 !important;"> (luaL_dostring(L,testfunc)) <br /></span><span style="color: #008080; line-height: 1.5 !important;">41</span>         printf(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">Failed to invoke.\n</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">); <br /></span><span style="color: #008080; line-height: 1.5 !important;">42</span> <span style="line-height: 1.5 !important;">    lua_close(L); </span><span style="color: #008080; line-height: 1.5 !important;">43</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #800080; line-height: 1.5 !important;">0</span><span style="line-height: 1.5 !important;">; </span><span style="color: #008080; line-height: 1.5 !important;">44</span> }</pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: 15px; color: #800080;">2. C函数库成为Lua的模块。</span><br />&nbsp;&nbsp; &nbsp;将包含C函数的代码生成库文件，如Linux的so，或Windows的DLL，同时拷贝到Lua代码所在的当前目录，或者是LUA_CPATH环境变量所指向的目录，以便于Lua解析器可以正确定位到他们。在我当前的Windows系统中，我将其copy到"C:\Program Files\Lua\5.1\clibs\"，这里包含了所有Lua可调用的C库。见如下C语言代码和关键性注释：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> #include &lt;stdio.h&gt; <span style="color: #008080; line-height: 1.5 !important;"> <br />2</span> #include &lt;<span style="color: #0000ff; line-height: 1.5 !important;">string</span>.h&gt; <span style="color: #008080; line-height: 1.5 !important;"> <br />3</span> #include &lt;lua.hpp&gt; <span style="color: #008080; line-height: 1.5 !important;"> <br />4</span> #include &lt;lauxlib.h&gt; <span style="color: #008080; line-height: 1.5 !important;"> <br />5</span> #include &lt;lualib.h&gt; <span style="color: #008080; line-height: 1.5 !important;"> <br />6</span>  <span style="color: #008080; line-height: 1.5 !important;"> <br />7</span> <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">待注册的C函数，该函数的声明形式在上面的例子中已经给出。 </span><span style="color: #008080; line-height: 1.5 !important;"> <br />8</span> <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">需要说明的是，该函数必须以C的形式被导出，因此extern "C"是必须的。 </span><span style="color: #008080; line-height: 1.5 !important;"> <br />9</span> <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">函数代码和上例相同，这里不再赘述。</span> <br /><span style="color: #008080; line-height: 1.5 !important;">10</span> <span style="color: #0000ff; line-height: 1.5 !important;">extern</span> <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">C</span><span style="color: #800000; line-height: 1.5 !important;">"</span> <span style="color: #0000ff; line-height: 1.5 !important;">int</span> add(lua_State*<span style="line-height: 1.5 !important;"> L)  <br /></span><span style="color: #008080; line-height: 1.5 !important;">11</span> <span style="line-height: 1.5 !important;">{ </span><span style="color: #008080; line-height: 1.5 !important;">12</span>     <span style="color: #0000ff; line-height: 1.5 !important;">double</span> op1 = luaL_checknumber(L,<span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">); <br /></span><span style="color: #008080; line-height: 1.5 !important;">13</span>     <span style="color: #0000ff; line-height: 1.5 !important;">double</span> op2 = luaL_checknumber(L,<span style="color: #800080; line-height: 1.5 !important;">2</span><span style="line-height: 1.5 !important;">); <br /></span><span style="color: #008080; line-height: 1.5 !important;">14</span>     lua_pushnumber(L,op1 +<span style="line-height: 1.5 !important;"> op2); <br /></span><span style="color: #008080; line-height: 1.5 !important;">15</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">; <br /></span><span style="color: #008080; line-height: 1.5 !important;">16</span> <span style="line-height: 1.5 !important;">} <br /></span><span style="color: #008080; line-height: 1.5 !important;">17</span>  <br /><span style="color: #008080; line-height: 1.5 !important;">18</span> <span style="color: #0000ff; line-height: 1.5 !important;">extern</span> <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">C</span><span style="color: #800000; line-height: 1.5 !important;">"</span> <span style="color: #0000ff; line-height: 1.5 !important;">int</span> sub(lua_State*<span style="line-height: 1.5 !important;"> L) <br /></span><span style="color: #008080; line-height: 1.5 !important;">19</span> <span style="line-height: 1.5 !important;">{ <br /></span><span style="color: #008080; line-height: 1.5 !important;">20</span>     <span style="color: #0000ff; line-height: 1.5 !important;">double</span> op1 = luaL_checknumber(L,<span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">);<br /></span><span style="color: #008080; line-height: 1.5 !important;">21</span>     <span style="color: #0000ff; line-height: 1.5 !important;">double</span> op2 = luaL_checknumber(L,<span style="color: #800080; line-height: 1.5 !important;">2</span><span style="line-height: 1.5 !important;">); <br /></span><span style="color: #008080; line-height: 1.5 !important;">22</span>     lua_pushnumber(L,op1 -<span style="line-height: 1.5 !important;"> op2); <br /></span><span style="color: #008080; line-height: 1.5 !important;">23</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">; <br /></span><span style="color: #008080; line-height: 1.5 !important;">24</span> <span style="line-height: 1.5 !important;">} <br /></span><span style="color: #008080; line-height: 1.5 !important;">25</span>  <br /><span style="color: #008080; line-height: 1.5 !important;">26</span> <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">luaL_Reg结构体的第一个字段为字符串，在注册时用于通知Lua该函数的名字。 <br /></span><span style="color: #008080; line-height: 1.5 !important;">27</span> <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">第一个字段为C函数指针。 <br /></span><span style="color: #008080; line-height: 1.5 !important;">28</span> <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">结构体数组中的最后一个元素的两个字段均为NULL，用于提示Lua注册函数已经到达数组的末尾。</span> <br /><span style="color: #008080; line-height: 1.5 !important;">29</span> <span style="color: #0000ff; line-height: 1.5 !important;">static</span> luaL_Reg mylibs[] =<span style="line-height: 1.5 !important;"> {  <br /></span><span style="color: #008080; line-height: 1.5 !important;">30</span>     {<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">add</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">, add}, <br /></span><span style="color: #008080; line-height: 1.5 !important;">31</span>     {<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">sub</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">, sub}, <br /></span><span style="color: #008080; line-height: 1.5 !important;">32</span> <span style="line-height: 1.5 !important;">    {NULL, NULL}  <br /></span><span style="color: #008080; line-height: 1.5 !important;">33</span> <span style="line-height: 1.5 !important;">};  <br /></span><span style="color: #008080; line-height: 1.5 !important;">34</span>  <br /><span style="color: #008080; line-height: 1.5 !important;">35</span> <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">该C库的唯一入口函数。其函数签名等同于上面的注册函数。见如下几点说明： <br /></span><span style="color: #008080; line-height: 1.5 !important;">36</span> <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">1. 我们可以将该函数简单的理解为模块的工厂函数。 <br /></span><span style="color: #008080; line-height: 1.5 !important;">37</span> <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">2. 其函数名必须为luaopen_xxx，其中xxx表示library名称。Lua代码require "xxx"需要与之对应。 <br /></span><span style="color: #008080; line-height: 1.5 !important;">38</span> <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">3. 在luaL_register的调用中，其第一个字符串参数为模块名"xxx"，第二个参数为待注册函数的数组。 <br /></span><span style="color: #008080; line-height: 1.5 !important;">39</span> <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">4. 需要强调的是，所有需要用到"xxx"的代码，不论C还是Lua，都必须保持一致，这是Lua的约定， <br /></span><span style="color: #008080; line-height: 1.5 !important;">40</span> <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">   否则将无法调用。</span> <br /><span style="color: #008080; line-height: 1.5 !important;">41</span> <span style="color: #0000ff; line-height: 1.5 !important;">extern</span> <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">C</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;"> __declspec(dllexport) <br /></span><span style="color: #008080; line-height: 1.5 !important;">42</span> <span style="color: #0000ff; line-height: 1.5 !important;">int</span> luaopen_mytestlib(lua_State*<span style="line-height: 1.5 !important;"> L)  <br /></span><span style="color: #008080; line-height: 1.5 !important;">43</span> <span style="line-height: 1.5 !important;">{ <br /></span><span style="color: #008080; line-height: 1.5 !important;">44</span>     <span style="color: #0000ff; line-height: 1.5 !important;">const</span> <span style="color: #0000ff; line-height: 1.5 !important;">char</span>* libName = <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">mytestlib</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">; <br /></span><span style="color: #008080; line-height: 1.5 !important;">45</span> <span style="line-height: 1.5 !important;">    luaL_register(L,libName,mylibs); <br /></span><span style="color: #008080; line-height: 1.5 !important;">46</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">; <br /></span><span style="color: #008080; line-height: 1.5 !important;">47</span> }</pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 见如下Lua代码：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #ff00ff; line-height: 1.5 !important;">require</span> <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">mytestlib</span><span style="color: #800000; line-height: 1.5 !important;">"</span>  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">指定包名称</span> <br /><span style="color: #008080; line-height: 1.5 !important;">2</span>  <br /><span style="color: #008080; line-height: 1.5 !important;">3</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">在调用时，必须是package.function</span> <br /><span style="color: #008080; line-height: 1.5 !important;">4</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(mytestlib.add(<span style="color: #800080; line-height: 1.5 !important;">1.0</span>,<span style="color: #800080; line-height: 1.5 !important;">2.0</span><span style="line-height: 1.5 !important;">)) <br /></span><span style="color: #008080; line-height: 1.5 !important;">5</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(mytestlib.sub(<span style="color: #800080; line-height: 1.5 !important;">20.1</span>,<span style="color: #800080; line-height: 1.5 !important;">19</span>))</pre></div><img src ="http://www.cppblog.com/mmdengwo/aggbug/205807.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mmdengwo/" target="_blank">沛沛</a> 2014-02-17 17:45 <a href="http://www.cppblog.com/mmdengwo/archive/2014/02/17/205807.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Step By Step(C调用Lua)</title><link>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205806.html</link><dc:creator>沛沛</dc:creator><author>沛沛</author><pubDate>Mon, 17 Feb 2014 09:44:00 GMT</pubDate><guid>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205806.html</guid><wfw:comment>http://www.cppblog.com/mmdengwo/comments/205806.html</wfw:comment><comments>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205806.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mmdengwo/comments/commentRss/205806.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mmdengwo/services/trackbacks/205806.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;1. 基础：&nbsp;&nbsp;&nbsp; Lua的一项重要用途就是作为一种配置语言。现在从一个简单的示例开始吧。&nbsp;&nbsp;&nbsp; --这里是用Lua代码定义的窗口大小的配置信息&nbsp;&nbsp;&nbsp; width = 200&nbsp;&nbsp;&nbsp; height = 300&nbsp;&nbsp;&nbsp; 下面是读取配置信息的C/...&nbsp;&nbsp;<a href='http://www.cppblog.com/mmdengwo/archive/2014/02/17/205806.html'>阅读全文</a><img src ="http://www.cppblog.com/mmdengwo/aggbug/205806.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mmdengwo/" target="_blank">沛沛</a> 2014-02-17 17:44 <a href="http://www.cppblog.com/mmdengwo/archive/2014/02/17/205806.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Step By Step(Lua-C API简介)</title><link>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205805.html</link><dc:creator>沛沛</dc:creator><author>沛沛</author><pubDate>Mon, 17 Feb 2014 09:44:00 GMT</pubDate><guid>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205805.html</guid><wfw:comment>http://www.cppblog.com/mmdengwo/comments/205805.html</wfw:comment><comments>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205805.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mmdengwo/comments/commentRss/205805.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mmdengwo/services/trackbacks/205805.html</trackback:ping><description><![CDATA[<p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp; &nbsp;Lua是一种嵌入式脚本语言，即Lua不是可以单独运行的程序，在实际应用中，主要存在两种应用形式。第一种形式是，C/C++作为主程序，调用Lua代码，此时可以将Lua看做&#8220;可扩展的语言&#8221;，我们将这种应用称为&#8220;应用程序代码&#8221;。第二种形式是Lua具有控制权，而C/C++代码则作为Lua的&#8220;库代码&#8221;。在这两种形式中，都是通过Lua提供的C API完成两种语言之间的通信的。<br /><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 1. 基础知识：</span><br />&nbsp;&nbsp; &nbsp;C API是一组能使C/C++代码与Lua交互的函数。其中包括读写Lua全局变量、调用Lua函数、运行一段Lua代码，以及注册C函数以供Lua代码调用等。这里先给出一个简单的示例代码：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> #include &lt;stdio.h&gt;<br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span> #include &lt;<span style="color: #0000ff; line-height: 1.5 !important;">string</span>.h&gt;<br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span> #include &lt;lua.hpp&gt;<br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span> #include &lt;lauxlib.h&gt;<br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span> #include &lt;lualib.h&gt;<br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span> <br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span> <span style="color: #0000ff; line-height: 1.5 !important;">int</span> main(<span style="color: #0000ff; line-height: 1.5 !important;">void</span>)<br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span> {<br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span>     <span style="color: #0000ff; line-height: 1.5 !important;">const</span> <span style="color: #0000ff; line-height: 1.5 !important;">char</span>* buff = <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">print(\"hello\")</span><span style="color: #800000; line-height: 1.5 !important;">"</span>;<br /><span style="color: #008080; line-height: 1.5 !important;">10</span>     <span style="color: #0000ff; line-height: 1.5 !important;">int</span> error;<br /><span style="color: #008080; line-height: 1.5 !important;">11</span>     lua_State* L = luaL_newstate();<br /><span style="color: #008080; line-height: 1.5 !important;">12</span>     luaL_openlibs(L);<br /><span style="color: #008080; line-height: 1.5 !important;">13</span> <br /><span style="color: #008080; line-height: 1.5 !important;">14</span>     error = luaL_loadbuffer(L,buff,strlen(buff),<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">line</span><span style="color: #800000; line-height: 1.5 !important;">"</span>) || lua_pcall(L,<span style="color: #800080; line-height: 1.5 !important;">0</span>,<span style="color: #800080; line-height: 1.5 !important;">0</span>,<span style="color: #800080; line-height: 1.5 !important;">0</span>);<br /><span style="color: #008080; line-height: 1.5 !important;">15</span>     <span style="color: #0000ff; line-height: 1.5 !important;">int</span> s = lua_gettop(L);<br /><span style="color: #008080; line-height: 1.5 !important;">16</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span> (error) {<br /><span style="color: #008080; line-height: 1.5 !important;">17</span>         fprintf(stderr,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">%s</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,lua_tostring(L,-<span style="color: #800080; line-height: 1.5 !important;">1</span>));<br /><span style="color: #008080; line-height: 1.5 !important;">18</span>         lua_pop(L,<span style="color: #800080; line-height: 1.5 !important;">1</span>);<br /><span style="color: #008080; line-height: 1.5 !important;">19</span>     }<br /><span style="color: #008080; line-height: 1.5 !important;">20</span>     lua_close(L);<br /><span style="color: #008080; line-height: 1.5 !important;">21</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #800080; line-height: 1.5 !important;">0</span>;<br /><span style="color: #008080; line-height: 1.5 !important;">22</span> }</pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 下面是针对以上代码给出的具体解释：<br />&nbsp;&nbsp; &nbsp;1). 上面的代码是基于我的C++工程，而非C工程，因此包含的头文件是lua.hpp，如果是C工程，可以直接包含lua.h。<br />&nbsp;&nbsp; &nbsp;2). Lua库中没有定义任何全局变量，而是将所有的状态都保存在动态结构lua_State中，后面所有的C API都需要该指针作为第一个参数。<br />&nbsp;&nbsp; &nbsp;3). luaL_openlibs函数是用于打开Lua中的所有标准库，如io库、string库等。<br />&nbsp;&nbsp; &nbsp;4). luaL_loadbuffer编译了buff中的Lua代码，如果没有错误，则返回0，同时将编译后的程序块压入虚拟栈中。<br />&nbsp;&nbsp; &nbsp;5). lua_pcall函数会将程序块从栈中弹出，并在保护模式下运行该程序块。执行成功返回0，否则将错误信息压入栈中。<br />&nbsp;&nbsp; &nbsp;6). lua_tostring函数中的-1，表示栈顶的索引值，栈底的索引值为1，以此类推。该函数将返回栈顶的错误信息，但是不会将其从栈中弹出。<br />&nbsp;&nbsp; &nbsp;7). lua_pop是一个宏，用于从虚拟栈中弹出指定数量的元素，这里的1表示仅弹出栈顶的元素。<br />&nbsp;&nbsp; &nbsp;8). lua_close用于释放状态指针所引用的资源。<br /><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 2. 栈：</span><br />&nbsp;&nbsp; &nbsp;在Lua和C语言之间进行数据交换时，由于两种语言之间有着较大的差异，比如Lua是动态类型，C语言是静态类型，Lua是自动内存管理，而C语言则是手动内存管理。为了解决这些问题，Lua的设计者使用了虚拟栈作为二者之间数据交互的介质。在C/C++程序中，如果要获取Lua的值，只需调用Lua的C API函数，Lua就会将指定的值压入栈中。要将一个值传给Lua时，需要先将该值压入栈，然后调用Lua的C API，Lua就会获取该值并将其从栈中弹出。为了可以将不同类型的值压入栈，以及从栈中取出不同类型的值，Lua为每种类型均设定了一个特定函数。<br />&nbsp;&nbsp; &nbsp;1). 压入元素：<br />&nbsp;&nbsp; &nbsp;Lua针对每种C类型，都有一个C API函数与之对应，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;void lua_pushnil(lua_State* L);&nbsp;&nbsp;<span style="color: #008000;">--nil值</span></span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;void lua_pushboolean(lua_State* L, int b);&nbsp;<span style="color: #008000;">--布尔值</span></span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;void lua_pushnumber(lua_State* L, lua_Number n);&nbsp;<span style="color: #008000;">--浮点数</span></span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;void lua_pushinteger(lua_State* L, lua_Integer n);&nbsp;&nbsp;<span style="color: #008000;">--整型</span></span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;void lua_pushlstring(lua_State* L, const char* s, size_t len);&nbsp;<span style="color: #008000;">--指定长度的内存数据</span></span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;void lua_pushstring(lua_State* L, const char* s);&nbsp;&nbsp;<span style="color: #008000;">--以零结尾的字符串，其长度可由strlen得出。</span></span><br />&nbsp;&nbsp; &nbsp;对于字符串数据，Lua不会持有他们的指针，而是调用在API时生成一个内部副本，因此，即使在这些函数返回后立刻释放或修改这些字符串指针，也不会有任何问题。<br />&nbsp;&nbsp; &nbsp;在向栈中压入数据时，可以通过调用下面的函数判断是否有足够的栈空间可用，一般而言，Lua会预留20个槽位，对于普通应用来说已经足够了，除非是遇到有很多参数的函数。<br /><span style="color: #008000;"><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;int lua_checkstack(lua_State* L, int extra)</span>&nbsp;--期望得到extra数量的空闲槽位，如果不能扩展并获得，返回false。</span>&nbsp;<br />&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp; &nbsp;2). 查询元素：<br />&nbsp;&nbsp; &nbsp;API使用&#8220;索引&#8221;来引用栈中的元素，第一个压入栈的为1，第二个为2，依此类推。我们也可以使用负数作为索引值，其中-1表示为栈顶元素，-2为栈顶下面的元素，同样依此类推。<br />&nbsp;&nbsp; &nbsp;Lua提供了一组特定的函数用于检查返回元素的类型，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;int lua_isboolean (lua_State *L, int index);</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;int lua_iscfunction (lua_State *L, int index);</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;int lua_isfunction (lua_State *L, int index);</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;int lua_isnil (lua_State *L, int index);</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;int lua_islightuserdata (lua_State *L, int index);</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;int lua_isnumber (lua_State *L, int index);</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;int lua_isstring (lua_State *L, int index);</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;int lua_istable (lua_State *L, int index);</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;int lua_isuserdata (lua_State *L, int index);</span><br />&nbsp;&nbsp; &nbsp;以上函数，成功返回1，否则返回0。需要特别指出的是，对于lua_isnumber而言，不会检查值是否为数字类型，而是检查值是否能转换为数字类型。<br />&nbsp;&nbsp; &nbsp;Lua还提供了一个函数lua_type，用于获取元素的类型，函数原型如下：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;int lua_type (lua_State *L, int index);</span><br />&nbsp;&nbsp; &nbsp;该函数的返回值为一组常量值，分别是：<span style="color: #0000ff;">LUA_TNIL、LUA_TNUMBER、LUA_TBOOLEAN、LUA_TSTRING、LUA_TTABLE、LUA_TFUNCTION、LUA_TUSERDATA、LUA_TTHREAD和LUA_TLIGHTUSERDATA</span>。这些常量通常用于switch语句中。<br />&nbsp;&nbsp; &nbsp;除了上述函数之外，Lua还提供了一组转换函数，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;int lua_toboolean (lua_State *L, int index);</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;lua_CFunction lua_tocfunction (lua_State *L, int index);</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;lua_Integer lua_tointeger (lua_State *L, int index);&nbsp;&nbsp; &nbsp;</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;const char *lua_tolstring (lua_State *L, int index, size_t *len);</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;lua_Number lua_tonumber (lua_State *L, int index);</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;const void *lua_topointer (lua_State *L, int index);</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;const char *lua_tostring (lua_State *L, int index);</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;void *lua_touserdata (lua_State *L, int index);</span><br /><span style="color: #008000;">&nbsp;&nbsp; &nbsp;--string类型返回字符串长度，table类型返回操作符'#'等同的结果，userdata类型返回分配的内存块长度。</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;size_t lua_objlen (lua_State *L, int index);　</span><br />&nbsp;&nbsp; &nbsp;对于上述函数，如果调用失败，lua_toboolean、lua_tonumber、lua_tointeger和lua_objlen均返回0，而其他函数则返回NULL。在很多时候0不是一个很有效的用于判断错误的值，但是ANSI C没有提供其他可以表示错误的值。因此对于这些函数，在有些情况下需要先使用lua_is*系列函数判断是否类型正确，而对于剩下的函数，则可以直接通过判断返回值是否为NULL即可。<br />&nbsp;&nbsp; &nbsp;对于lua_tolstring函数返回的指向内部字符串的指针，在该索引指向的元素被弹出之后，将无法保证仍然有效。该函数返回的字符串末尾均会有一个尾部0。<br />&nbsp;&nbsp; &nbsp;下面将给出一个工具函数，可用于演示上面提到的部分函数，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #0000ff; line-height: 1.5 !important;">static</span> <span style="color: #0000ff; line-height: 1.5 !important;">void</span> stackDump(lua_State* L) <br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span> {<br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span>     <span style="color: #0000ff; line-height: 1.5 !important;">int</span> top = lua_gettop(L);<br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span>     <span style="color: #0000ff; line-height: 1.5 !important;">for</span> (<span style="color: #0000ff; line-height: 1.5 !important;">int</span> i = <span style="color: #800080; line-height: 1.5 !important;">1</span>; i &lt;= top; ++i) {<br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span>         <span style="color: #0000ff; line-height: 1.5 !important;">int</span> t = lua_type(L,i);<br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span>         <span style="color: #0000ff; line-height: 1.5 !important;">switch</span>(t) {<br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span>         <span style="color: #0000ff; line-height: 1.5 !important;">case</span> LUA_TSTRING:<br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span>             printf(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">'%s'</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,lua_tostring(L,i));<br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span>             <span style="color: #0000ff; line-height: 1.5 !important;">break</span>;<br /><span style="color: #008080; line-height: 1.5 !important;">10</span>         <span style="color: #0000ff; line-height: 1.5 !important;">case</span> LUA_TBOOLEAN:<br /><span style="color: #008080; line-height: 1.5 !important;">11</span>             printf(lua_toboolean(L,i) ? <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">true</span><span style="color: #800000; line-height: 1.5 !important;">"</span> : <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">false</span><span style="color: #800000; line-height: 1.5 !important;">"</span>);<br /><span style="color: #008080; line-height: 1.5 !important;">12</span>             <span style="color: #0000ff; line-height: 1.5 !important;">break</span>;<br /><span style="color: #008080; line-height: 1.5 !important;">13</span>         <span style="color: #0000ff; line-height: 1.5 !important;">case</span> LUA_TNUMBER:<br /><span style="color: #008080; line-height: 1.5 !important;">14</span>             printf(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">%g</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,lua_tonumber(L,i));<br /><span style="color: #008080; line-height: 1.5 !important;">15</span>             <span style="color: #0000ff; line-height: 1.5 !important;">break</span>;<br /><span style="color: #008080; line-height: 1.5 !important;">16</span>         <span style="color: #0000ff; line-height: 1.5 !important;">default</span>:<br /><span style="color: #008080; line-height: 1.5 !important;">17</span>             printf(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">%s</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,lua_typename(L,t));<br /><span style="color: #008080; line-height: 1.5 !important;">18</span>             <span style="color: #0000ff; line-height: 1.5 !important;">break</span>;<br /><span style="color: #008080; line-height: 1.5 !important;">19</span>         }<br /><span style="color: #008080; line-height: 1.5 !important;">20</span>         printf(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">"</span>);<br /><span style="color: #008080; line-height: 1.5 !important;">21</span>     }<br /><span style="color: #008080; line-height: 1.5 !important;">22</span>     printf(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">\n</span><span style="color: #800000; line-height: 1.5 !important;">"</span>);<br /><span style="color: #008080; line-height: 1.5 !important;">23</span> }</pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 3). 其它栈操作函数：<br />&nbsp;&nbsp; &nbsp;除了上面给出的数据交换函数之外，Lua的C API还提供了一组用于操作虚拟栈的普通函数，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;int lua_gettop(lua_State* L);&nbsp;<span style="color: #008000;">--返回栈中元素的个数。</span></span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;void lua_settop(lua_State* L, int index);&nbsp;<span style="color: #008000;">--将栈顶设置为指定的索引值。</span></span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;void lua_pushvalue(lua_State* L, int index);&nbsp;<span style="color: #008000;">--将指定索引的元素副本压入栈。</span></span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;void lua_remove(lua_State* L, int index);&nbsp;<span style="color: #008000;">--删除指定索引上的元素，其上面的元素自动下移。</span></span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;void lua_insert(lua_State* L, int index);&nbsp;<span style="color: #008000;">--将栈顶元素插入到该索引值指向的位置。</span></span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;void lua_replace(lua_State* L, int index);&nbsp;<span style="color: #008000;">--弹出栈顶元素，并将该值设置到指定索引上。</span></span><br />&nbsp;&nbsp; &nbsp;Lua还提供了一个宏用于弹出指定数量的元素：<span style="color: #0000ff;">#define lua_pop(L,n)&nbsp; lua_settop(L, -(n) - 1)&nbsp;&nbsp; &nbsp;</span><br />&nbsp;&nbsp; &nbsp;见如下示例代码：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #0000ff; line-height: 1.5 !important;">int</span> main()<br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span> {<br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span>     lua_State* L = luaL_newstate();<br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span>     lua_pushboolean(L,<span style="color: #800080; line-height: 1.5 !important;">1</span>);<br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span>     lua_pushnumber(L,<span style="color: #800080; line-height: 1.5 !important;">10</span>);<br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span>     lua_pushnil(L);<br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span>     lua_pushstring(L,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">hello</span><span style="color: #800000; line-height: 1.5 !important;">"</span>);<br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span>     stackDump(L); <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">true 10 nil 'hello'</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 9</span> <br /><span style="color: #008080; line-height: 1.5 !important;">10</span>     lua_pushvalue(L,-<span style="color: #800080; line-height: 1.5 !important;">4</span>);<br /><span style="color: #008080; line-height: 1.5 !important;">11</span>     stackDump(L); <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">true 10 nil 'hello' true</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">12</span> <br /><span style="color: #008080; line-height: 1.5 !important;">13</span>     lua_replace(L,<span style="color: #800080; line-height: 1.5 !important;">3</span>);<br /><span style="color: #008080; line-height: 1.5 !important;">14</span>     stackDump(L); <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">true 10 true 'hello'</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">15</span> <br /><span style="color: #008080; line-height: 1.5 !important;">16</span>     lua_settop(L,<span style="color: #800080; line-height: 1.5 !important;">6</span>);<br /><span style="color: #008080; line-height: 1.5 !important;">17</span>     stackDump(L); <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">true 10 true 'hello' nil nil</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">18</span> <br /><span style="color: #008080; line-height: 1.5 !important;">19</span>     lua_remove(L,-<span style="color: #800080; line-height: 1.5 !important;">3</span>);<br /><span style="color: #008080; line-height: 1.5 !important;">20</span>     stackDump(L); <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">true 10 true nil nil</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">21</span> <br /><span style="color: #008080; line-height: 1.5 !important;">22</span>     lua_settop(L,-<span style="color: #800080; line-height: 1.5 !important;">5</span>);<br /><span style="color: #008080; line-height: 1.5 !important;">23</span>     stackDump(L); <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">true</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">24</span> <br /><span style="color: #008080; line-height: 1.5 !important;">25</span>     lua_close(L);<br /><span style="color: #008080; line-height: 1.5 !important;">26</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #800080; line-height: 1.5 !important;">0</span>;<br /><span style="color: #008080; line-height: 1.5 !important;">27</span> }</pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 3. C API中的错误处理：</span><br />&nbsp;&nbsp; &nbsp;1). C程序调用Lua代码的错误处理：<br />&nbsp;&nbsp; &nbsp;通常情况下，应用程序代码是以&#8220;无保护&#8221;模式运行的。因此，当Lua发现&#8220;内存不足&#8221;这类错误时，只能通过调用&#8220;紧急&#8221;函数来通知C语言程序，之后在结束应用程序。用户可通过<span style="color: #0000ff;">lua_atpanic</span>来设置自己的&#8220;紧急&#8221;函数。如果希望应用程序代码在发生Lua错误时不会退出，可通过调用<span style="color: #0000ff;">lua_pcall</span>函数以保护模式运行Lua代码。这样再发生内存错误时，lua_pcall会返回一个错误代码，并将解释器重置为一致的状态。如果要保护与Lua的C代码，可以使用<span style="color: #0000ff;">lua_cpall</span>函数，它将接受一个C函数作为参数，然后调用这个C函数。<br />&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp; &nbsp;2). Lua调用C程序：<br />&nbsp;&nbsp; &nbsp;通常而言，当一个被Lua调用的C函数检测到错误时，它就应该调用<span style="color: #0000ff;">lua_error</span>，该函数会清理Lua中所有需要清理的资源，然后跳转回发起执行的那个lua_pcall，并附上一条错误信息。</p><img src ="http://www.cppblog.com/mmdengwo/aggbug/205805.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mmdengwo/" target="_blank">沛沛</a> 2014-02-17 17:44 <a href="http://www.cppblog.com/mmdengwo/archive/2014/02/17/205805.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Step By Step(Lua系统库)</title><link>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205804.html</link><dc:creator>沛沛</dc:creator><author>沛沛</author><pubDate>Mon, 17 Feb 2014 09:43:00 GMT</pubDate><guid>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205804.html</guid><wfw:comment>http://www.cppblog.com/mmdengwo/comments/205804.html</wfw:comment><comments>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205804.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mmdengwo/comments/commentRss/205804.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mmdengwo/services/trackbacks/205804.html</trackback:ping><description><![CDATA[<p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp; Lua为了保证高度的可移植性，因此，它的标准库仅仅提供了非常少的功能，特别是和OS相关的库。但是Lua还提供了一些扩展库，比如Posix库等。对于文件操作而言，该库仅提供了<span style="color: #0000ff;">os.rename</span>函数和<span style="color: #0000ff;">os.remove</span>函数。<br />&nbsp;&nbsp; &nbsp;<br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp; &nbsp;1. 日期和时间：</span><br />&nbsp;&nbsp; &nbsp;在Lua中，函数<span style="color: #0000ff;">time</span>和<span style="color: #0000ff;">date</span>提供了所有的日期和时间功能。<br />&nbsp;&nbsp; &nbsp;如果不带任何参数调用time函数，它将以数字形式返回当前的日期和时间。如果以一个table作为参数，它将返回一个数字，表示该table中所描述的日期和时间。该table的有效字段如下：</p><table border="0" align="center" style="border-style: solid; border-color: silver; border-collapse: collapse; color: #000000; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px; line-height: 18px; width: 600px;"><tbody><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><strong><span style="color: #0000ff;">字段名</span></strong></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><strong><span style="color: #0000ff;">描述</span></strong></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">year</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">一个完整的年份</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">month</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">01-12</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">day</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">01-31</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">hour</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">00-23</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">min</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">00-59</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">sec</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">00-59</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">isdst</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">布尔值，true表示夏令时</span></td></tr></tbody></table><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff;">print(os.time{year = 1970, month = 1, day = 1, hour = 8, min = 0})&nbsp;<span style="color: #008000;">--北京是东八区，所以hour等于时表示UTC的0。</span></span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000;"><span style="color: #0000ff;">print(os.time())</span>&nbsp; --输出当前时间距离1970-1-1 00:00:00所经过的秒数。输出值为 1333594721</span><br />&nbsp;&nbsp;&nbsp; 函数date是time的反函数，即可以将time返回的数字值转换为更高级的可读格式，其第一个参数是格式化字符串，表示期望的日期返回格式，第二个参数是日期和时间的数字，缺省为当前日期和时间。如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> dd = <span style="color: #ff00ff; line-height: 1.5 !important;">os.date</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">*t</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,<span style="color: #ff00ff; line-height: 1.5 !important;">os.time</span>())  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">如果格式化字符串为"*t"，函数将返回table形式的日期对象。</span><span style="color: #008000; line-height: 1.5 !important;">如果为"!*t"，则表示为UTC时间格式。<br /></span><span style="color: #008080; line-height: 1.5 !important;"> 2</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">year = </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. dd.year)<br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">month = </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. dd.month)<br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">day = </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. dd.day)<br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">weekday = </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. dd.wday)  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">一个星期中的第几天，周日是第一天</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 6</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">yearday = </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. dd.yday)  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">一年中的第几天，1月1日是第一天</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 7</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">hour = </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. dd.hour)<br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">min = </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. dd.min)<br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">sec = </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. dd.sec)<br /><span style="color: #008080; line-height: 1.5 !important;">10</span>     <br /><span style="color: #008080; line-height: 1.5 !important;">11</span> <span style="color: #008000; line-height: 1.5 !important;">--[[</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">12</span> <span style="color: #008000; line-height: 1.5 !important;">year = 2012<br /></span><span style="color: #008080; line-height: 1.5 !important;">13</span> <span style="color: #008000; line-height: 1.5 !important;">month = 4<br /></span><span style="color: #008080; line-height: 1.5 !important;">14</span> <span style="color: #008000; line-height: 1.5 !important;">day = 5<br /></span><span style="color: #008080; line-height: 1.5 !important;">15</span> <span style="color: #008000; line-height: 1.5 !important;">weekday = 5<br /></span><span style="color: #008080; line-height: 1.5 !important;">16</span> <span style="color: #008000; line-height: 1.5 !important;">yearday = 96<br /></span><span style="color: #008080; line-height: 1.5 !important;">17</span> <span style="color: #008000; line-height: 1.5 !important;">hour = 11<br /></span><span style="color: #008080; line-height: 1.5 !important;">18</span> <span style="color: #008000; line-height: 1.5 !important;">min = 13<br /></span><span style="color: #008080; line-height: 1.5 !important;">19</span> <span style="color: #008000; line-height: 1.5 !important;">sec = 44<br /></span><span style="color: #008080; line-height: 1.5 !important;">20</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">]]</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; date函数的格式化标识和C运行时库中的strftime函数的标识完全相同，见下表：</p><table border="0" align="center" style="border-style: solid; border-color: silver; border-collapse: collapse; color: #000000; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px; line-height: 18px; width: 600px;"><tbody><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><strong><span style="color: #0000ff;">关键字</span></strong></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><strong><span style="color: #0000ff;">描述</span></strong></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%a</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">一星期中天数的缩写，如Wed</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%A</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">一星期中天数的全称，如Friday</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%b</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">月份的缩写，如Sep</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%B</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">月份的全称，如September</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%c</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">日期和时间</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%d</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">一个月中的第几天(01-31)</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%H</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">24小时制中的小时数(00-23)</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%I</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">12小时制中的小时数(01-12)</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%j</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">一年中的第几天(001-366)</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%M</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">分钟(00-59)</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%m</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">月份(01-12)</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%p</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">"上午(am)"或"下午(pm)"</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%S</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">秒数(00-59)</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%w</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">一星期中的第几天(0--6等价于星期日--星期六)</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%x</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">日期，如09/16/2010</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%X</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">时间，如23:48:20</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%y</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">两位数的年份(00-99)</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%Y</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">完整的年份(2012)</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%%</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">字符'%'</span></td></tr></tbody></table><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff;">print(os.date("%Y-%m-%d"))&nbsp;<span style="color: #008000;">&nbsp;--输出2012-04-05</span></span><br />&nbsp;&nbsp;&nbsp; 函数os.clock()返回CPU时间的描述，通常用于计算一段代码的执行效率。如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> x = <span style="color: #ff00ff; line-height: 1.5 !important;">os.clock</span>()<br /><span style="color: #008080; line-height: 1.5 !important;">2</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> s = <span style="color: #800080; line-height: 1.5 !important;">0</span><br /><span style="color: #008080; line-height: 1.5 !important;">3</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> i = <span style="color: #800080; line-height: 1.5 !important;">1</span>, <span style="color: #800080; line-height: 1.5 !important;">10000000</span> <span style="color: #0000ff; line-height: 1.5 !important;">do</span> <br /><span style="color: #008080; line-height: 1.5 !important;">4</span>     s = s + i <br /><span style="color: #008080; line-height: 1.5 !important;">5</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">6</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #ff00ff; line-height: 1.5 !important;">string.format</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">elapsed time: %.2f\n</span><span style="color: #800000; line-height: 1.5 !important;">"</span>, <span style="color: #ff00ff; line-height: 1.5 !important;">os.clock</span>() - x))<br /><span style="color: #008080; line-height: 1.5 !important;">7</span> <br /><span style="color: #008080; line-height: 1.5 !important;">8</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出结果为：</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">9</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">elapsed time: 0.21    </span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp; &nbsp;2. 其他系统调用：</span><br />&nbsp;&nbsp; &nbsp;函数<span style="color: #0000ff;">os.exit()</span>可中止当前程序的执行。函数<span style="color: #0000ff;">os.getenv()</span>可获取一个环境变量的值。如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;print(os.getenv("PATH"))&nbsp;&nbsp;<span style="color: #008000;">--如果环境变量不存在，返回nil。</span></span><br />&nbsp;&nbsp; &nbsp;<span style="color: #0000ff;">os.execute</span>函数用于执行和操作系统相关的命令，如：<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000ff;">&nbsp;os.execute("mkdir " .. "hello")</span></p><img src ="http://www.cppblog.com/mmdengwo/aggbug/205804.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mmdengwo/" target="_blank">沛沛</a> 2014-02-17 17:43 <a href="http://www.cppblog.com/mmdengwo/archive/2014/02/17/205804.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Step By Step(Lua输入输出库)</title><link>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205803.html</link><dc:creator>沛沛</dc:creator><author>沛沛</author><pubDate>Mon, 17 Feb 2014 09:43:00 GMT</pubDate><guid>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205803.html</guid><wfw:comment>http://www.cppblog.com/mmdengwo/comments/205803.html</wfw:comment><comments>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205803.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mmdengwo/comments/commentRss/205803.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mmdengwo/services/trackbacks/205803.html</trackback:ping><description><![CDATA[<p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp; I/O库为文件操作提供了两种不同的模型，简单模型和完整模型。简单模型假设一个当前输入文件和一个当前输出文件，他的I/O操作均作用于这些文件。完整模型则使用显式的文件句柄，并将所有的操作定义为文件句柄上的方法。<br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp; &nbsp;1. 简单模型：</span><br />&nbsp;&nbsp; &nbsp;I/O库会将进程标准输入输出作为其缺省的输入文件和输出文件。我们可以通过<span style="color: #0000ff;">io.input(filename)</span>和<span style="color: #0000ff;">io.output(filename)</span>这两个函数来改变当前的输入输出文件。<br />&nbsp;&nbsp; &nbsp;1). io.write函数：<br />&nbsp;&nbsp; &nbsp;函数原型为io.write(...)。该函数将所有参数顺序的写入到当前输出文件中。如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;io.write("hello","world")&nbsp;<span style="color: #008000;">--写出的内容为helloworld</span></span><br /><br />&nbsp;&nbsp; &nbsp;2). io.read函数：<br />&nbsp;&nbsp; &nbsp;下表给出了该函数参数的定义和功能描述：</p><table border="0" align="center" style="border-style: solid; border-color: silver; border-collapse: collapse; color: #000000; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px; line-height: 18px; width: 600px;"><tbody><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><strong><span style="color: #0000ff;">参数字符串</span></strong></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><strong><span style="color: #0000ff;">含义</span></strong></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">"*all"</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">读取整个文件</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">"*line"</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">读取下一行</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">"*number"</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">读取一个数字</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">&lt;num&gt;</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">读取一个不超过&lt;num&gt;个字符的字符串</span></td></tr></tbody></table><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 调用<span style="color: #0000ff;">io.read("*all")</span>会读取当前输入文件的所有内容，以当前位置作为开始。如果当前位置处于文件的末尾，或者文件为空，那个该调用返回一个空字符串。由于Lua可以高效的处理长字符串，因此在Lua中可以先将数据从文件中完整读出，之后在通过Lua字符串库提供的函数进行各种处理。<br />&nbsp;&nbsp; &nbsp;调用<span style="color: #0000ff;">io.read("*line")</span>会返回当前文件的下一行，但不包含换行符。当到达文件末尾时，该调用返回nil。如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> count = <span style="color: #800080; line-height: 1.5 !important;">1</span>,<span style="color: #ff00ff; line-height: 1.5 !important;">math.huge</span> <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">2</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> line = <span style="color: #ff00ff; line-height: 1.5 !important;">io.read</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">*line</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">如果不传参数，缺省值也是"*line"</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">3</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span> line == <span style="color: #0000ff; line-height: 1.5 !important;">nil</span> <span style="color: #0000ff; line-height: 1.5 !important;">then</span> <br /><span style="color: #008080; line-height: 1.5 !important;">4</span>         <span style="color: #0000ff; line-height: 1.5 !important;">break</span><br /><span style="color: #008080; line-height: 1.5 !important;">5</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">6</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">io.write</span>(<span style="color: #ff00ff; line-height: 1.5 !important;">string.format</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">%6d  </span><span style="color: #800000; line-height: 1.5 !important;">"</span>,count),line,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">\n</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">7</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 如果只是为了迭代文件中的所有行，可以使用<span style="color: #0000ff;">io.lines</span>函数，以迭代器的形式访问文件中的每一行数据，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> lines = {}<br /><span style="color: #008080; line-height: 1.5 !important;">2</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> line <span style="color: #0000ff; line-height: 1.5 !important;">in</span> <span style="color: #ff00ff; line-height: 1.5 !important;">io.lines</span>() <span style="color: #0000ff; line-height: 1.5 !important;">do</span>   <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">通过迭代器访问每一个数据</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">3</span>     lines[#lines + <span style="color: #800080; line-height: 1.5 !important;">1</span>] = line<br /><span style="color: #008080; line-height: 1.5 !important;">4</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">5</span> <span style="color: #ff00ff; line-height: 1.5 !important;">table.sort</span>(lines)  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">排序，Lua标准库的table库提供的函数。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">6</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> _,l <span style="color: #0000ff; line-height: 1.5 !important;">in</span> <span style="color: #ff00ff; line-height: 1.5 !important;">ipairs</span>(lines) <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">7</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">io.write</span>(l,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">\n</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">8</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 调用<span style="color: #0000ff;">io.read("*number")</span>会从当前输入文件中读取一个数字。此时read将直接返回一个数字，而不是字符串。"*number"选项会忽略数字前面所有的空格，并且能处理像-3、+5.2这样的数字格式。如果当前读取的数据不是合法的数字，read返回nil。在调用read是可以指定多个选项，函数会根据每个选项参数返回相应的内容。如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #008000; line-height: 1.5 !important;">--[[</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 2</span> <span style="color: #008000; line-height: 1.5 !important;">    6.0  -3.23   1000<br /></span><span style="color: #008080; line-height: 1.5 !important;"> 3</span> <span style="color: #008000; line-height: 1.5 !important;">    ... ...<br /></span><span style="color: #008080; line-height: 1.5 !important;"> 4</span> <span style="color: #008000; line-height: 1.5 !important;">    下面的代码读取注释中的数字<br /></span><span style="color: #008080; line-height: 1.5 !important;"> 5</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">]]</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span> <span style="color: #0000ff; line-height: 1.5 !important;">while</span> <span style="color: #0000ff; line-height: 1.5 !important;">true</span> <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> n1,n2,n3 = <span style="color: #ff00ff; line-height: 1.5 !important;">io.read</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">*number</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">*number</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">*number</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span> <span style="color: #0000ff; line-height: 1.5 !important;">not</span> n1 <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span>         <span style="color: #0000ff; line-height: 1.5 !important;">break</span><br /><span style="color: #008080; line-height: 1.5 !important;">10</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">11</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #ff00ff; line-height: 1.5 !important;">math.max</span>(n1,n2,n3))<br /><span style="color: #008080; line-height: 1.5 !important;">12</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 调用<span style="color: #0000ff;">io.read(&lt;num&gt;)</span>会从输入文件中最多读取n个字符，如果读不到任何字符，返回nil。否则返回读取到的字符串。如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">while</span> <span style="color: #0000ff; line-height: 1.5 !important;">true</span> <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">2</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> block = <span style="color: #ff00ff; line-height: 1.5 !important;">io.read</span>(<span style="color: #800080; line-height: 1.5 !important;">2</span>^<span style="color: #800080; line-height: 1.5 !important;">13</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">3</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span> <span style="color: #0000ff; line-height: 1.5 !important;">not</span> block <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;">4</span>         <span style="color: #0000ff; line-height: 1.5 !important;">break</span><br /><span style="color: #008080; line-height: 1.5 !important;">5</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">6</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">io.write</span>(block)<br /><span style="color: #008080; line-height: 1.5 !important;">7</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp;<span style="color: #0000ff;">&nbsp;io.read(0)</span>是一种特殊的情况，用于检查是否到达了文件的末尾。如果没有到达，返回空字符串，否则nil。<br /><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 2. 完整I/O模型：</span><br />&nbsp;&nbsp; &nbsp;Lua中完整I/O模型的使用方式非常类似于C运行时库的文件操作函数，它们都是基于文件句柄的。<br />&nbsp;&nbsp; &nbsp;1). 通过<span style="color: #0000ff;">io.open</span>函数打开指定的文件，并且在参数中给出对该文件的打开模式，其中<span style="color: #0000ff;">"r"</span>表示读取，<span style="color: #0000ff;">"w"</span>表示覆盖写入，即先删除文件原有的内容，<span style="color: #0000ff;">"a"</span>表示追加式写入，<span style="color: #0000ff;">"b"</span>表示以二进制的方式打开文件。在成功打开文件后，该函数将返回表示该文件的句柄，后面所有基于该文件的操作，都需要将该句柄作为参数传入。如果打开失败，返回nil。其中错误信息由该函数的第二个参数返回，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;assert(io.open(filename,mode))&nbsp;&nbsp;<span style="color: #008000;">--如果打开失败，assert将打印第二个参数给出的错误信息。</span></span><br />&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp; &nbsp;2). 文件读写函数<span style="color: #0000ff;">read/write</span>。这里需要用到冒号语法，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> f = <span style="color: #ff00ff; line-height: 1.5 !important;">assert</span>(<span style="color: #ff00ff; line-height: 1.5 !important;">io.open</span>(filename,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">r</span><span style="color: #800000; line-height: 1.5 !important;">"</span>))<br /><span style="color: #008080; line-height: 1.5 !important;">2</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> t = f:read(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">*all</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">对于read而言，其参数完全等同于简单模型下read的参数。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">3</span> f:close()</pre></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 此外，I/O库还提供了3个预定义的文件句柄，即<span style="color: #0000ff;">io.stdin(标准输入)、io.stdout(标准输出)、io.stderr(标准错误输出)</span>。如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;io.stderr:write("This is an error message.")</span><br />&nbsp;&nbsp; &nbsp;事实上，我们也可以混合使用简单模式和完整模式，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> temp = <span style="color: #ff00ff; line-height: 1.5 !important;">io.input</span>()   <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">将当前文件句柄保存</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">2</span> <span style="color: #ff00ff; line-height: 1.5 !important;">io.input</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">newInputfile</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">打开新的输入文件</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">3</span> <span style="color: #ff00ff; line-height: 1.5 !important;">io.input</span>():close()        <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">关闭当前文件</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">4</span> <span style="color: #ff00ff; line-height: 1.5 !important;">io.input</span>(temp)            <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">恢复原来的输入文件</span></pre></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><br />&nbsp;&nbsp;&nbsp; 3). 性能小技巧：<br />&nbsp;&nbsp; &nbsp;由于一次性读取整个文件比逐行读取要快一些，但对于较大的文件，这样并不可行，因此Lua提供了一种折中的方式，即一次读取指定字节数量的数据，如果当前读取中的最后一行不是完整的一行，可通过该方式将该行的剩余部分也一并读入，从而保证本次读取的数据均为整行数据，以便于上层逻辑的处理。如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;local lines,rest = f:read(BUFSIZE,"*line")&nbsp;<span style="color: #008000;">--rest变量包含最后一行中没有读取的部分。</span></span><br />&nbsp;&nbsp; &nbsp;下面是Shell中wc命令的一个简单实现。</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> BUFSIZE = <span style="color: #800080; line-height: 1.5 !important;">8192</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> f = <span style="color: #ff00ff; line-height: 1.5 !important;">io.input</span>(arg[<span style="color: #800080; line-height: 1.5 !important;">1</span>])  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">打开输入文件</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 3</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> cc, lc, wc, = <span style="color: #800080; line-height: 1.5 !important;">0</span>, <span style="color: #800080; line-height: 1.5 !important;">0</span>, <span style="color: #800080; line-height: 1.5 !important;">0</span>  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">分别计数字符、行和单词    </span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 4</span> <span style="color: #0000ff; line-height: 1.5 !important;">while</span> <span style="color: #0000ff; line-height: 1.5 !important;">true</span> <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> lines,rest = f:read(BUFSIZE,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">*line</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span> <span style="color: #0000ff; line-height: 1.5 !important;">not</span> lines <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span>         <span style="color: #0000ff; line-height: 1.5 !important;">break</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span> rest <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;">10</span>         lines = lines .. rest .. <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">\n</span><span style="color: #800000; line-height: 1.5 !important;">"</span><br /><span style="color: #008080; line-height: 1.5 !important;">11</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">12</span>     cc = cc + #lines<br /><span style="color: #008080; line-height: 1.5 !important;">13</span>     <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">计算单词数量</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">14</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> _, t = <span style="color: #ff00ff; line-height: 1.5 !important;">string.gsub</span>(lines.<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">%S+</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,<span style="color: #800000; line-height: 1.5 !important;">""</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">15</span>     wc = wc + t<br /><span style="color: #008080; line-height: 1.5 !important;">16</span>     <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">计算行数</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">17</span>     _,t = <span style="color: #ff00ff; line-height: 1.5 !important;">string.gsub</span>(line,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">\n</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">\n</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">18</span>     lc = lc + t<br /><span style="color: #008080; line-height: 1.5 !important;">19</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">20</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(lc,wc,cc)</pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><br />&nbsp;&nbsp;&nbsp; 4). 其它文件操作：<br />&nbsp;&nbsp; &nbsp;如<span style="color: #0000ff;">io.flush</span>函数会将io缓存中的数据刷新到磁盘文件上。<span style="color: #0000ff;">io.close</span>函数将关闭当前打开的文件。<span style="color: #0000ff;">io.seek</span>函数用于设置或获取当前文件的读写位置，其函数原型为<span style="color: #0000ff;">f:seek(whence,offset)</span>，如果whence的值为<span style="color: #0000ff;">"set"</span>，offset的值则表示为相对于文件起始位置的偏移量。如为<span style="color: #0000ff;">"cur"(默认值)</span>,offset则为相对于当前位置的偏移量，如为<span style="color: #0000ff;">"end"</span>，则为相对于文件末尾的偏移量。函数的返回值与whence参数无关，总是返回文件的当前位置，即相对于文件起始处的偏移字节数。offset的默认值为0。如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> fsize(file)<br /><span style="color: #008080; line-height: 1.5 !important;">2</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> current = <span style="color: #ff00ff; line-height: 1.5 !important;">file:seek</span>()   <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">获取当前位置</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">3</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> size = <span style="color: #ff00ff; line-height: 1.5 !important;">file:seek</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">end</span><span style="color: #800000; line-height: 1.5 !important;">"</span>) <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">获取文件大小</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">4</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">file:seek</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">set</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,current)      <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">恢复原有的当前位置</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">5</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> size<br /><span style="color: #008080; line-height: 1.5 !important;">6</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 最后需要指出的是，如果发生错误，所有这些函数均返回nil和一条错误信息。</p><img src ="http://www.cppblog.com/mmdengwo/aggbug/205803.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mmdengwo/" target="_blank">沛沛</a> 2014-02-17 17:43 <a href="http://www.cppblog.com/mmdengwo/archive/2014/02/17/205803.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Step By Step(Lua字符串库)</title><link>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205802.html</link><dc:creator>沛沛</dc:creator><author>沛沛</author><pubDate>Mon, 17 Feb 2014 09:42:00 GMT</pubDate><guid>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205802.html</guid><wfw:comment>http://www.cppblog.com/mmdengwo/comments/205802.html</wfw:comment><comments>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205802.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mmdengwo/comments/commentRss/205802.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mmdengwo/services/trackbacks/205802.html</trackback:ping><description><![CDATA[<p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><span style="color: #800080; font-size: 15px;">1. 基础字符串函数：</span><br />&nbsp;&nbsp; &nbsp;字符串库中有一些函数非常简单，如：<br />&nbsp;&nbsp; &nbsp;1).&nbsp;string.len(s) 返回字符串s的长度；<br />&nbsp;&nbsp; &nbsp;2). string.rep(s,n) 返回字符串s重复n次的结果；<br />&nbsp;&nbsp; &nbsp;3). string.lower(s) 返回s的副本，其中所有的大写都被转换为了小写形式，其他字符不变；<br />&nbsp;&nbsp; &nbsp;4). string.upper(s) 和lower相反，将小写转换为大写；<br />&nbsp;&nbsp; &nbsp;5). string.sub(s,i,j) 提取字符串s的第i个到第j个字符。Lua中，第一个字符的索引值为1，最后一个为-1，以此类推，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;print(string.sub("[hello world]",2,-2))&nbsp; &nbsp; &nbsp;&nbsp;<span style="color: #008000;">--输出hello world</span></span><br />&nbsp;&nbsp; &nbsp;6). string.format(s,...) 返回格式化后的字符串，其格式化规则等同于C语言中printf函数，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;print(string.format("pi = %.4f",math.pi))&nbsp;<span style="color: #008000;">--输出pi = 3.1416</span></span><br />&nbsp;&nbsp; &nbsp;7). string.char(...) 参数为0到多个整数，并将每个整数转换为对应的字符。然后返回一个由这些字符连接而成的字符串，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;print(string.char(97,98,99))&nbsp;<span style="color: #008000;">--输出abc</span></span><br />&nbsp;&nbsp; &nbsp;8). string.byte(s,i) 返回字符串s的第i个字符的Ascii值，如果没有第二个参数，缺省返回第一个字符的Ascii值。<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;print(string.byte("abc"))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000;">--输出97</span></span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;print(string.byte("abc",-1))&nbsp;&nbsp;<span style="color: #008000;">--输出99</span></span><br />&nbsp;&nbsp;&nbsp; 由于字符串类型的变量都是不可变类型的变量，因此在所有和string相关的函数中，都无法改变参数中的字符串值，而是生成一个新值返回。<br /><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp; &nbsp;2. 模式匹配函数：</span><br />&nbsp;&nbsp; &nbsp;Lua的字符串库提供了一组强大的模式匹配函数，如find、match、gsub和gmatch。<br />&nbsp;&nbsp; &nbsp;1). string.find函数：<br />&nbsp;&nbsp; &nbsp;在目标字符串中搜索一个模式，如果找到，则返回匹配的起始索引和结束索引，否则返回nil。如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> s = <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">hello world</span><span style="color: #800000; line-height: 1.5 !important;">"</span><br /><span style="color: #008080; line-height: 1.5 !important;">2</span> i, j = <span style="color: #ff00ff; line-height: 1.5 !important;">string.find</span>(s,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">hello</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)  <br /><span style="color: #008080; line-height: 1.5 !important;">3</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(i, j)        <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出1  5</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">4</span> i, j = <span style="color: #ff00ff; line-height: 1.5 !important;">string.find</span>(s,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">l</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">5</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(i, j)        <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出3  3</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">6</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #ff00ff; line-height: 1.5 !important;">string.find</span>(s,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">lll</span><span style="color: #800000; line-height: 1.5 !important;">"</span>))  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出nil</span></pre></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; string.find函数还有一个可选参数，它是一个索引，用于告诉函数从目标字符串的哪个位置开始搜索。主要用于搜索目标字符串中所有匹配的子字符串，且每次搜索都从上一次找到的位置开始。如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> t = {}<br /><span style="color: #008080; line-height: 1.5 !important;">2</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> i = <span style="color: #800080; line-height: 1.5 !important;">0</span><br /><span style="color: #008080; line-height: 1.5 !important;">3</span> <span style="color: #0000ff; line-height: 1.5 !important;">while</span> <span style="color: #0000ff; line-height: 1.5 !important;">true</span> <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">4</span>     i = <span style="color: #ff00ff; line-height: 1.5 !important;">string.find</span>(s,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">\n</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,i+<span style="color: #800080; line-height: 1.5 !important;">1</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">5</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span> i == <span style="color: #0000ff; line-height: 1.5 !important;">nil</span> <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;">6</span>         <span style="color: #0000ff; line-height: 1.5 !important;">break</span><br /><span style="color: #008080; line-height: 1.5 !important;">7</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">8</span>     t[#t + <span style="color: #800080; line-height: 1.5 !important;">1</span>] = i<br /><span style="color: #008080; line-height: 1.5 !important;">9</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 2). string.match函数：<br />&nbsp;&nbsp; &nbsp;该函数返回目标字符串中和模式字符串匹配的部分。如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> date = <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">Today is 2012-01-01</span><span style="color: #800000; line-height: 1.5 !important;">"</span><br /><span style="color: #008080; line-height: 1.5 !important;">2</span> d = <span style="color: #ff00ff; line-height: 1.5 !important;">string.match</span>(date,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">%d+\-%d+\-%d+</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">3</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(d)  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出2012-01-01</span></pre></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 3). string.gsub函数：<br />&nbsp;&nbsp; &nbsp;该函数有3个参数，目标字符串、模式和替换字符串。基本用法是将目标字符串中所有出现模式的地方替换为替换字符串。如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;print(string.gsub("Lua is cute","cute","great"))&nbsp;&nbsp;<span style="color: #008000;">--输出Lua is great</span></span><br />&nbsp;&nbsp; &nbsp;该函数还有可选的第4个参数，即实际替换的次数。<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;print(string.gsub("all lii","l","x",1))&nbsp;<span style="color: #008000;">&nbsp;--输出axl lii</span></span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;print(string.gsub("all lii","l","x",2))&nbsp;&nbsp;<span style="color: #008000;">--输出axx lii</span></span><br />&nbsp;&nbsp; &nbsp;函数string.gsub还有另一个结果，即实际替换的次数。<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;count = select(2, string.gsub(str," "," "))</span>&nbsp;<span style="color: #008000;">&nbsp;--输出str中空格的数量</span><br /><br />&nbsp;&nbsp;&nbsp; 4). string.gmatch函数：<br />&nbsp;&nbsp; &nbsp;返回一个函数，通过这个返回的函数可以遍历到一个字符串中所有出现指定模式的地方。如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> words = {}<br /><span style="color: #008080; line-height: 1.5 !important;">2</span> s = <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">hello world</span><span style="color: #800000; line-height: 1.5 !important;">"</span><br /><span style="color: #008080; line-height: 1.5 !important;">3</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> w <span style="color: #0000ff; line-height: 1.5 !important;">in</span> <span style="color: #ff00ff; line-height: 1.5 !important;">string.gmatch</span>(s,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">%a+</span><span style="color: #800000; line-height: 1.5 !important;">"</span>) <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">4</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(w)<br /><span style="color: #008080; line-height: 1.5 !important;">5</span>     words[#words + <span style="color: #800080; line-height: 1.5 !important;">1</span>] = w<br /><span style="color: #008080; line-height: 1.5 !important;">6</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">7</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出结果为：</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">8</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">hello</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">9</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">world</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 3. 模式：</span><br />&nbsp;&nbsp; &nbsp;下面的列表给出了Lua目前支持的模式元字符；</p><table border="0" align="center" style="border-style: solid; border-color: silver; border-collapse: collapse; color: #000000; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px; line-height: 18px; width: 600px;"><tbody><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><strong><span style="color: #0000ff;">模式元字符</span></strong></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><strong><span style="color: #0000ff;">描述</span></strong></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">.</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">所有字符</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%a</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">字母</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%c</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">控制字符</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%d</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">数字</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%l</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">小写字母</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%p</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">标点符号</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%s</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">空白字符</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%u</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">大写字母</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%w</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">字母和数字字符</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%x</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">十六进制数字</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%z</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">内部表示为0的字符</span></td></tr></tbody></table><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 这些元字符的大写形式表示它们的补集，如%A，表示所有非字母字符。<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;print(string.gsub("hello, up-down!","%S","."))&nbsp;&nbsp;&nbsp;<span style="color: #008000;">--输出hello..up.down. 4</span></span><br />&nbsp;&nbsp; &nbsp;上例中的4表示替换的次数。<br />&nbsp;&nbsp; &nbsp;除了上述元字符之外，Lua还提供了另外几个关键字符。如<strong><span style="color: #0000ff;">：( ) . % + - * ? [ ] ^ $</span></strong><br />&nbsp;&nbsp; &nbsp;其中<strong><span style="color: #0000ff;">%</span></strong>表示转义字符，如%.表示点(.)，%%表示百分号(%)。<br />&nbsp;&nbsp; &nbsp;方括号<strong><span style="color: #0000ff;">[]</span></strong>表示将不同的字符分类，即可创建出属于自己的字符分类，如[%w_]表示匹配字符、数字和下划线。<br />&nbsp;&nbsp; &nbsp;横线(<strong><span style="color: #0000ff;">-</span></strong>)表示连接一个范围，比如[0-9A-Z]<br />&nbsp;&nbsp; &nbsp;如果<strong><span style="color: #0000ff;">^</span></strong>字符在方括号内，如[^\n]，表示除\n之外的所有字符，即表示方括号中的分类的补集。如果^不在方括号内，则表示以后面的字符开头，<strong><span style="color: #0000ff;">$</span></strong>和它正好相反，表示以前面的字符结束。如：^Hello%d$，匹配的字符串可能为Hello1、Hello2等。<br />&nbsp;&nbsp; &nbsp;在Lua中还提供了4种用来修饰模式中的重复部分，如：<span style="color: #0000ff;">+(重复1次或多次)、*(重复0次或多次)、-(重复0次或多次)和?(出现0或1次)</span>。如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;print(string.gsub("one, and two; and three","%a+","word"))&nbsp;<span style="color: #008000;">--输出word, word word; word word</span></span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;print(string.match("the number 1298 is even","%d+"))&nbsp;<span style="color: #008000;">--输出1298</span></span><br />&nbsp;&nbsp; &nbsp;星号(<strong><span style="color: #0000ff;">*</span></strong>)和横线(<strong><span style="color: #0000ff;">-</span></strong>)的主要差别是，星号总是试图匹配更多的字符，而横线则总是试图匹配最少的字符。<br /><br />&nbsp;<span style="color: #800080; font-size: 15px;">&nbsp;&nbsp; 4. 捕获(capture)：</span><br />&nbsp;&nbsp; &nbsp;捕获功能可根据一个模式从目标字符串中抽出匹配于该模式的内容。在指定捕获是，应将模式中需要捕获的部分写到一对圆括号内。对于具有捕获的模式，函数string.match会将所有捕获到的值作为单独的结果返回。即它会将目标字符串切成多个捕获到的部分。如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> pair = <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">name = Anna</span><span style="color: #800000; line-height: 1.5 !important;">"</span><br /><span style="color: #008080; line-height: 1.5 !important;">2</span> key,value = <span style="color: #ff00ff; line-height: 1.5 !important;">string.match</span>(pair,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">(%a+)%s*=%s*(%a+)</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">3</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(key,value)  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出name anna</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">4</span> <br /><span style="color: #008080; line-height: 1.5 !important;">5</span> date = <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">Today is 2012-01-02</span><span style="color: #800000; line-height: 1.5 !important;">"</span><br /><span style="color: #008080; line-height: 1.5 !important;">6</span> y,m,d = <span style="color: #ff00ff; line-height: 1.5 !important;">string.match</span>(date,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">(%d+)\-(%d+)\-(%d+)</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">7</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(y,m,d)      <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出2012    01      02</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 还可以对模式本身使用捕获。即<strong><span style="color: #0000ff;">%1</span></strong>表示第一个捕获，以此类推，<strong><span style="color: #0000ff;">%0</span></strong>表示整个匹配，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #ff00ff; line-height: 1.5 !important;">string.gsub</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">hello Lua</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">(.)(.)</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">%2%1</span><span style="color: #800000; line-height: 1.5 !important;">"</span>))  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">将相邻的两个字符对调，输出为ehll ouLa</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">2</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #ff00ff; line-height: 1.5 !important;">string.gsub</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">hello Lua!</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">%a</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">%0-%0</span><span style="color: #800000; line-height: 1.5 !important;">"</span>))    <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出为h-he-el-ll-lo-o L-Lu-ua-a!</span></pre></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 5. 替换：</span><br />&nbsp;&nbsp; &nbsp;string.gsub函数的第三个参数不仅可以是字符串，也可以是函数或table，如果是函数，string.gsub会在每次找到匹配时调用该函数，调用时的参数就是捕获到的内容，而该函数的返回值则作为要替换的字符串。当用一个table来调用时，string.gsub会用每次捕获到的内容作为key，在table中查找，并将对应的value作为要替换的字符串。如果table中不包含这个key，那么string.gsub不改变这个匹配。如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> expand(s)<br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> (<span style="color: #ff00ff; line-height: 1.5 !important;">string.gsub</span>(s,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">$(%w+)</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,<span style="color: #008080; line-height: 1.5 !important;">_G</span>))<br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span> <br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span> name = <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">Lua</span><span style="color: #800000; line-height: 1.5 !important;">"</span>; status = <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">great</span><span style="color: #800000; line-height: 1.5 !important;">"</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(expand(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">$name is $status, isn't it?</span><span style="color: #800000; line-height: 1.5 !important;">"</span>))  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出 Lua is great, isn't it?</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 7</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(expand(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">$othername is $status, isn't it?</span><span style="color: #800000; line-height: 1.5 !important;">"</span>))  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出 $othername is great, isn't it?</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 8</span> <br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> expand2(s)<br /><span style="color: #008080; line-height: 1.5 !important;">10</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> (<span style="color: #ff00ff; line-height: 1.5 !important;">string.gsub</span>(s,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">$(%w+)</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,<span style="color: #0000ff; line-height: 1.5 !important;">function</span>(n) <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #ff00ff; line-height: 1.5 !important;">tostring</span>(<span style="color: #008080; line-height: 1.5 !important;">_G</span>[n]) <span style="color: #0000ff; line-height: 1.5 !important;">end</span>))<br /><span style="color: #008080; line-height: 1.5 !important;">11</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">12</span> <br /><span style="color: #008080; line-height: 1.5 !important;">13</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(expand2(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">print = $print; a = $a</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)) <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出 print = function: 002B77C0; a = nil</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><img src ="http://www.cppblog.com/mmdengwo/aggbug/205802.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mmdengwo/" target="_blank">沛沛</a> 2014-02-17 17:42 <a href="http://www.cppblog.com/mmdengwo/archive/2014/02/17/205802.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Step By Step(Lua弱引用table)</title><link>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205801.html</link><dc:creator>沛沛</dc:creator><author>沛沛</author><pubDate>Mon, 17 Feb 2014 09:41:00 GMT</pubDate><guid>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205801.html</guid><wfw:comment>http://www.cppblog.com/mmdengwo/comments/205801.html</wfw:comment><comments>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205801.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mmdengwo/comments/commentRss/205801.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mmdengwo/services/trackbacks/205801.html</trackback:ping><description><![CDATA[<p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;Lua采用了基于垃圾收集的内存管理机制，因此对于程序员来说，在很多时候内存问题都将不再困扰他们。然而任何垃圾收集器都不是万能的，在有些特殊情况下，垃圾收集器是无法准确的判断是否应该将当前对象清理。这样就极有可能导致很多垃圾对象无法被释放。为了解决这一问题，就需要Lua的开发者予以一定程度上的配合。比如，当某个table对象被存放在容器中，而容器的外部不再有任何变量引用该对象，对于这样的对象，Lua的垃圾收集器是不会清理的，因为容器对象仍然引用着他。如果此时针对该容器的应用仅限于查找，而不是遍历的话，那么该对象将永远不会被用到。事实上，对于这样的对象我们是希望Lua的垃圾收集器可以将其清理掉的。见如下代码：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> a = {}<br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span> key = {}<br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span> a[key] = <span style="color: #800080; line-height: 1.5 !important;">1</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span> key = {}<br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span> a[key] = <span style="color: #800080; line-height: 1.5 !important;">2</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span> <span style="color: #ff00ff; line-height: 1.5 !important;">collectgarbage</span>()<br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> k,v <span style="color: #0000ff; line-height: 1.5 !important;">in</span> <span style="color: #ff00ff; line-height: 1.5 !important;">pairs</span>(a) <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(v)<br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span>    <br /><span style="color: #008080; line-height: 1.5 !important;">10</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出1和2</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 在执行垃圾收集之后，table a中的两个key都无法被清理，但是对value等于1的key而言，如果后面的逻辑不会遍历table a的话，那么我们就可以认为该对象内存泄露了。在Lua中提供了一种被称为弱引用table的机制，可以提示垃圾收集器，如果某个对象，如上面代码中的第一个table key，只是被弱引用table引用，那么在执行垃圾收集时可以将其清理。<br />&nbsp;&nbsp; &nbsp;Lua中的弱引用表提供了3中弱引用模式，即key是弱引用、value是弱引用，以及key和value均是弱引用。不论是哪种类型的弱引用table，只要有一个key或value被回收，那么它们所在的整个条目都会从table中删除。<br />&nbsp;&nbsp; &nbsp;一个table的弱引用类型是通过其元表的<span style="color: #0000ff;">__mode</span>字段来决定的。如果该值为包含字符<strong><span style="color: #0000ff;">"k"</span></strong>，那么table就是key弱引用，如果包含<strong><span style="color: #0000ff;">"v"</span></strong>，则是value若引用，如果两个字符均存在，就是key/value弱引用。见如下代码：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> a = {}<br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span> b = {__mode = <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">k</span><span style="color: #800000; line-height: 1.5 !important;">"</span>}<br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span> <span style="color: #ff00ff; line-height: 1.5 !important;">setmetatable</span>(a,b)<br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span> key = {}<br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span> a[key] = <span style="color: #800080; line-height: 1.5 !important;">1</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span> key = {}<br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span> a[key] = <span style="color: #800080; line-height: 1.5 !important;">2</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span> <span style="color: #ff00ff; line-height: 1.5 !important;">collectgarbage</span>()<br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> k,v <span style="color: #0000ff; line-height: 1.5 !important;">in</span> <span style="color: #ff00ff; line-height: 1.5 !important;">pairs</span>(a) <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">10</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(v)<br /><span style="color: #008080; line-height: 1.5 !important;">11</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span>    <br /><span style="color: #008080; line-height: 1.5 !important;">12</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">仅仅输出2</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 在上面的代码示例中，第一个key在被存放到table a之后，就被第二个key的定义所覆盖，因此它的唯一引用来自key弱引用表。事实上，这种机制在Java中也同样存在，Java在1.5之后的版本中也提供了一组弱引用容器，其语义和Lua的弱引用table相似。<br />&nbsp;&nbsp;&nbsp; 最后需要说明的是，Lua中的弱引用表只是作用于table类型的变量，对于其他类型的变量，如数值和字符串等，弱引用表并不起任何作用。<br /><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 1. 备忘录(memoize)函数：</span><br />&nbsp;&nbsp; &nbsp;用&#8220;空间换时间&#8221;是一种通用的程序运行效率优化手段，比如：对于一个普通的Server，它接受到的请求中包含Lua代码，每当其收到请求后都会调用Lua的loadstring函数来动态解析请求中的Lua代码，如果这种操作过于频率，就会导致Server的执行效率下降。要解决该问题，我们可以将每次解析的结果缓存到一个table中，下次如果接收到相同的Lua代码，就不需要调用loadstirng来动态解析了，而是直接从table中获取解析后的函数直接执行即可。这样在有大量重复Lua代码的情况下，可以极大的提高Server的执行效率。反之，如果有相当一部分的Lua代码只是出现一次，那么再使用这种机制，就将会导致大量的内存资源被占用而得不到有效的释放。在这种情况下，如果使用弱引用表，不仅可以在一定程度上提升程序的运行效率，内存资源也会得到有效的释放。见如下代码：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> results = {}<br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span> <span style="color: #ff00ff; line-height: 1.5 !important;">setmetatable</span>(results,{__mode = <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">v</span><span style="color: #800000; line-height: 1.5 !important;">"</span>}) <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">results表中的key是字符串形式的Lua代码</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 3</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> mem_loadstring(s)<br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> res = results[s]<br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span> res == <span style="color: #0000ff; line-height: 1.5 !important;">nil</span> <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span>         res = <span style="color: #ff00ff; line-height: 1.5 !important;">assert</span>(<span style="color: #ff00ff; line-height: 1.5 !important;">loadstring</span>(s))<br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span>         results[s] = res<br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> res<br /><span style="color: #008080; line-height: 1.5 !important;">10</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><img src ="http://www.cppblog.com/mmdengwo/aggbug/205801.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mmdengwo/" target="_blank">沛沛</a> 2014-02-17 17:41 <a href="http://www.cppblog.com/mmdengwo/archive/2014/02/17/205801.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Step By Step(Lua面向对象)</title><link>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205800.html</link><dc:creator>沛沛</dc:creator><author>沛沛</author><pubDate>Mon, 17 Feb 2014 09:41:00 GMT</pubDate><guid>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205800.html</guid><wfw:comment>http://www.cppblog.com/mmdengwo/comments/205800.html</wfw:comment><comments>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205800.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mmdengwo/comments/commentRss/205800.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mmdengwo/services/trackbacks/205800.html</trackback:ping><description><![CDATA[<div id="cnblogs_post_body" style="margin-bottom: 20px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><p style="margin-top: 10px; margin-bottom: 10px;">Lua中的table就是一种对象，但是如果直接使用仍然会存在大量的问题，见如下代码：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> Account = {balance = <span style="color: #800080; line-height: 1.5 !important;">0</span>}<br /><span style="color: #008080; line-height: 1.5 !important;">2</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> Account.withdraw(v)<br /><span style="color: #008080; line-height: 1.5 !important;">3</span>     Account.balance = Account.balance - v<br /><span style="color: #008080; line-height: 1.5 !important;">4</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">5</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">下面是测试调用函数</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">6</span> Account.withdraw(<span style="color: #800080; line-height: 1.5 !important;">100.00</span>)</pre></div><p style="margin-top: 10px; margin-bottom: 10px;">&nbsp;&nbsp;&nbsp; 在上面的withdraw函数内部依赖了全局变量Account，一旦该变量发生改变，将会导致withdraw不再能正常的工作，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> a = Account; Account = <span style="color: #0000ff; line-height: 1.5 !important;">nil</span><br /><span style="color: #008080; line-height: 1.5 !important;">2</span> a.withdraw(<span style="color: #800080; line-height: 1.5 !important;">100.00</span>)  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">将会导致访问空nil的错误。</span></pre></div><p style="margin-top: 10px; margin-bottom: 10px;">&nbsp;&nbsp;&nbsp; 这种行为明显的违反了面向对象封装性和实例独立性。要解决这一问题，我们需要给withdraw函数在添加一个参数<span style="color: #0000ff;">self</span>，他等价于Java/C++中的this，见如下修改：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> Account.withdraw(self,v)<br /><span style="color: #008080; line-height: 1.5 !important;">2</span>     self.balance = self.balance - v<br /><span style="color: #008080; line-height: 1.5 !important;">3</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">4</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">下面是基于修改后代码的调用：</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">5</span> a1 = Account; Account = <span style="color: #0000ff; line-height: 1.5 !important;">nil</span><br /><span style="color: #008080; line-height: 1.5 !important;">6</span> a1.withdraw(a1,<span style="color: #800080; line-height: 1.5 !important;">100.00</span>)  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">正常工作。</span></pre></div><p style="margin-top: 10px; margin-bottom: 10px;">&nbsp;&nbsp;&nbsp; 针对上述问题，Lua提供了一种更为便利的语法，即将点<strong><span style="color: #0000ff;">(.)</span></strong>替换为冒号<strong><span style="color: #0000ff;">(:)</span></strong>，这样可以在定义和调用时均隐藏self参数，如:</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> Account:withdraw(v)<br /><span style="color: #008080; line-height: 1.5 !important;">2</span>     self.balance = self.balance - v<br /><span style="color: #008080; line-height: 1.5 !important;">3</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">4</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">调用代码可改为：</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">5</span> a:withdraw(<span style="color: #800080; line-height: 1.5 !important;">100.00</span>)</pre></div><p style="margin-top: 10px; margin-bottom: 10px;"><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #800080; font-size: 15px;">1. 类：</span><br />&nbsp;&nbsp; &nbsp;Lua在语言上并没有提供面向对象的支持，因此想实现该功能，我们只能通过table来模拟，见如下代码及关键性注释：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #008000; line-height: 1.5 !important;">--[[</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 2</span> <span style="color: #008000; line-height: 1.5 !important;">在这段代码中，我们可以将Account视为class的声明，如Java中的：<br /></span><span style="color: #008080; line-height: 1.5 !important;"> 3</span> <span style="color: #008000; line-height: 1.5 !important;">public class Account <br /></span><span style="color: #008080; line-height: 1.5 !important;"> 4</span> <span style="color: #008000; line-height: 1.5 !important;">{<br /></span><span style="color: #008080; line-height: 1.5 !important;"> 5</span> <span style="color: #008000; line-height: 1.5 !important;">    public float balance = 0;<br /></span><span style="color: #008080; line-height: 1.5 !important;"> 6</span> <span style="color: #008000; line-height: 1.5 !important;">    public Account(Account o);<br /></span><span style="color: #008080; line-height: 1.5 !important;"> 7</span> <span style="color: #008000; line-height: 1.5 !important;">    public void deposite(float f);<br /></span><span style="color: #008080; line-height: 1.5 !important;"> 8</span> <span style="color: #008000; line-height: 1.5 !important;">}<br /></span><span style="color: #008080; line-height: 1.5 !important;"> 9</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">]]</span><br /><span style="color: #008080; line-height: 1.5 !important;">10</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">这里balance是一个公有的成员变量。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">11</span> Account = {balance = <span style="color: #800080; line-height: 1.5 !important;">0</span>}<br /><span style="color: #008080; line-height: 1.5 !important;">12</span> <br /><span style="color: #008080; line-height: 1.5 !important;">13</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">new可以视为构造函数</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">14</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> Account:new(o)<br /><span style="color: #008080; line-height: 1.5 !important;">15</span>     o = o <span style="color: #0000ff; line-height: 1.5 !important;">or</span> {} <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">如果参数中没有提供table，则创建一个空的。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">16</span>     <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">将新对象实例的metatable指向Account表(类)，这样就可以将其视为模板了。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">17</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">setmetatable</span>(o,self)<br /><span style="color: #008080; line-height: 1.5 !important;">18</span>     <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">在将Account的__index字段指向自己，以便新对象在访问Account的函数和字段时，可被直接重定向。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">19</span>     self.__index = self<br /><span style="color: #008080; line-height: 1.5 !important;">20</span>     <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">最后返回构造后的对象实例</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">21</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> o<br /><span style="color: #008080; line-height: 1.5 !important;">22</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">23</span> <br /><span style="color: #008080; line-height: 1.5 !important;">24</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">deposite被视为Account类的公有成员函数</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">25</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> Account:deposit(v)<br /><span style="color: #008080; line-height: 1.5 !important;">26</span>     <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">这里的self表示对象实例本身</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">27</span>     self.balance = self.balance + v<br /><span style="color: #008080; line-height: 1.5 !important;">28</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">29</span> <br /><span style="color: #008080; line-height: 1.5 !important;">30</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">下面的代码创建两个Account的对象实例</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">31</span> <br /><span style="color: #008080; line-height: 1.5 !important;">32</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">通过Account的new方法构造基于该类的示例对象。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">33</span> a = Account:new()<br /><span style="color: #008080; line-height: 1.5 !important;">34</span> <span style="color: #008000; line-height: 1.5 !important;">--[[</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">35</span> <span style="color: #008000; line-height: 1.5 !important;">这里需要具体解释一下，此时由于table a中并没有deposite字段，因此需要重定向到Account，<br /></span><span style="color: #008080; line-height: 1.5 !important;">36</span> <span style="color: #008000; line-height: 1.5 !important;">同时调用Account的deposite方法。在Account.deposite方法中，由于self(a对象)并没有balance<br /></span><span style="color: #008080; line-height: 1.5 !important;">37</span> <span style="color: #008000; line-height: 1.5 !important;">字段，因此在执行self.balance + v时，也需要重定向访问Account中的balance字段，其缺省值为0。<br /></span><span style="color: #008080; line-height: 1.5 !important;">38</span> <span style="color: #008000; line-height: 1.5 !important;">在得到计算结果后，再将该结果直接赋值给a.balance。此后a对象就拥有了自己的balance字段和值。<br /></span><span style="color: #008080; line-height: 1.5 !important;">39</span> <span style="color: #008000; line-height: 1.5 !important;">下次再调用该方法，balance字段的值将完全来自于a对象，而无需在重定向到Account了。<br /></span><span style="color: #008080; line-height: 1.5 !important;">40</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">]]</span><br /><span style="color: #008080; line-height: 1.5 !important;">41</span> a:deposit(<span style="color: #800080; line-height: 1.5 !important;">100.00</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">42</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(a.balance) <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出100</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">43</span> <br /><span style="color: #008080; line-height: 1.5 !important;">44</span> b = Account:new()<br /><span style="color: #008080; line-height: 1.5 !important;">45</span> b:deposit(<span style="color: #800080; line-height: 1.5 !important;">200.00</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">46</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(b.balance) <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出200</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px;"><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 2. 继承：</span><br />&nbsp;&nbsp; &nbsp;继承也是面向对象中一个非常重要的概念，在Lua中我们仍然可以像模拟类那样来进一步实现面向对象中的继承机制，见如下代码及关键性注释：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">需要说明的是，这段代码仅提供和继承相关的注释，和类相关的注释在上面的代码中已经给出。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 2</span> Account = {balance = <span style="color: #800080; line-height: 1.5 !important;">0</span>}<br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span> <br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> Account:new(o)<br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span>     o = o <span style="color: #0000ff; line-height: 1.5 !important;">or</span> {}<br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">setmetatable</span>(o,self)<br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span>     self.__index = self<br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> o<br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">10</span> <br /><span style="color: #008080; line-height: 1.5 !important;">11</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> Account:deposit(v)<br /><span style="color: #008080; line-height: 1.5 !important;">12</span>     self.balance = self.balance + v<br /><span style="color: #008080; line-height: 1.5 !important;">13</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">14</span> <br /><span style="color: #008080; line-height: 1.5 !important;">15</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> Account:withdraw(v)<br /><span style="color: #008080; line-height: 1.5 !important;">16</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span> v &gt; self.balance <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;">17</span>         <span style="color: #ff00ff; line-height: 1.5 !important;">error</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">Insufficient funds</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">18</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">19</span>     self.balance = self.balance - v<br /><span style="color: #008080; line-height: 1.5 !important;">20</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">21</span> <br /><span style="color: #008080; line-height: 1.5 !important;">22</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">下面将派生出一个Account的子类，以使客户可以实现透支的功能。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">23</span> SpecialAccount = Account:new()  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">此时SpecialAccount仍然为Account的一个对象实例</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">24</span> <br /><span style="color: #008080; line-height: 1.5 !important;">25</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">派生类SpecialAccount扩展出的方法。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">26</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">下面这些SpecialAccount中的方法代码(getLimit/withdraw)，一定要位于SpecialAccount被Account构造之后。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">27</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> SpecialAccount:getLimit()<br /><span style="color: #008080; line-height: 1.5 !important;">28</span>     <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">此时的self将为对象实例。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">29</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> self.limit <span style="color: #0000ff; line-height: 1.5 !important;">or</span> <span style="color: #800080; line-height: 1.5 !important;">0</span><br /><span style="color: #008080; line-height: 1.5 !important;">30</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">31</span> <br /><span style="color: #008080; line-height: 1.5 !important;">32</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">SpecialAccount将为Account的子类，下面的方法withdraw可以视为SpecialAccount</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">33</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">重写的Account中的withdraw方法，以实现自定义的功能。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">34</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> SpecialAccount:withdraw(v)<br /><span style="color: #008080; line-height: 1.5 !important;">35</span>     <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">此时的self将为对象实例。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">36</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span> v - self.balance &gt;= self:getLimit() <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;">37</span>         <span style="color: #ff00ff; line-height: 1.5 !important;">error</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">Insufficient funds</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">38</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">39</span>     self.balance = self.balance - v<br /><span style="color: #008080; line-height: 1.5 !important;">40</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">41</span> <br /><span style="color: #008080; line-height: 1.5 !important;">42</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">在执行下面的new方法时，table s的元表已经是SpecialAccount了，而不再是Account。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">43</span> s = SpecialAccount:new{limit = <span style="color: #800080; line-height: 1.5 !important;">1000.00</span>}<br /><span style="color: #008080; line-height: 1.5 !important;">44</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">在调用下面的deposit方法时，由于table s和SpecialAccount均未提供该方法，因此访问的仍然是</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">45</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">Account的deposit方法。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">46</span> s:deposit(<span style="color: #800080; line-height: 1.5 !important;">100</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">47</span> <br /><span style="color: #008080; line-height: 1.5 !important;">48</span> <br /><span style="color: #008080; line-height: 1.5 !important;">49</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">此时的withdraw方法将不再是Account中的withdraw方法，而是SpecialAccount中的该方法。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">50</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">这是因为Lua先在SpecialAccount(即s的元表)中找到了该方法。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">51</span> s:withdraw(<span style="color: #800080; line-height: 1.5 !important;">200.00</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">52</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(s.balance) <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出-100</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px;"><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 3. 私密性：</span><br />&nbsp;&nbsp; &nbsp;私密性对于面向对象语言来说是不可或缺的，否则将直接破坏对象的封装性。Lua作为一种面向过程的脚本语言，更是没有提供这样的功能，然而和模拟支持类与继承一样，我们仍然可以在Lua中通过特殊的编程技巧来实现它，这里我们应用的是Lua中的闭包函数。该实现方式和前面两个示例中基于元表的方式有着很大的区别，见如下代码示例和关键性注释：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">这里我们需要一个闭包函数作为类的创建工厂</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 2</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> newAccount(initialBalance)<br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span>     <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">这里的self仅仅是一个普通的局部变量，其含义完全不同于前面示例中的self。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 4</span>     <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">这里之所以使用self作为局部变量名，也是为了方便今后的移植。比如，以后</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 5</span>     <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">如果改为上面的实现方式，这里应用了self就可以降低修改的工作量了。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 6</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> self = {balance = initialBalance} <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">这里我们可以将self视为私有成员变量</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 7</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> withdraw = <span style="color: #0000ff; line-height: 1.5 !important;">function</span>(v) self.balance = self.balance - v <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> deposit = <span style="color: #0000ff; line-height: 1.5 !important;">function</span>(v) self.balance = self.balance + v <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> getBalance = <span style="color: #0000ff; line-height: 1.5 !important;">function</span>() <span style="color: #0000ff; line-height: 1.5 !important;">return</span> self.balance <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">10</span>     <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">返回对象中包含的字段仅仅为公有方法。事实上，我们通过该种方式，不仅可以实现</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">11</span>     <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">成员变量的私有性，也可以实现方法的私有性，如：</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">12</span>     <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">local privateFunction = function() --do something end</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">13</span>     <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">只要我们不在输出对象中包含该方法的字段即可。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">14</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> {withdraw = withdraw, deposit = deposit, getBalance = getBalance}<br /><span style="color: #008080; line-height: 1.5 !important;">15</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">16</span> <br /><span style="color: #008080; line-height: 1.5 !important;">17</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">和前面两个示例不同的是，在调用对象方法时，不再需要self变量，因此我们可以直接使用点(.)，</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">18</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">而不再需要使用冒号(:)操作符了。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">19</span> accl = newAccount(<span style="color: #800080; line-height: 1.5 !important;">100.00</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">20</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">在函数newAccount返回之后，该函数内的&#8220;非局部变量&#8221;表self就不再能被外部访问了，只能通过</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">21</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">该函数返回的对象的方法来操作它们。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">22</span> accl.withdraw(<span style="color: #800080; line-height: 1.5 !important;">40.00</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">23</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(acc1.getBalance())</pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px;">&nbsp;&nbsp;&nbsp; 事实上，上面的代码只是给出一个简单的示例，在实际应用中，我们可以将更多的私有变量存放于上例的局部self表中。</p></div><img src ="http://www.cppblog.com/mmdengwo/aggbug/205800.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mmdengwo/" target="_blank">沛沛</a> 2014-02-17 17:41 <a href="http://www.cppblog.com/mmdengwo/archive/2014/02/17/205800.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Step By Step(Lua模块与包)</title><link>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205798.html</link><dc:creator>沛沛</dc:creator><author>沛沛</author><pubDate>Mon, 17 Feb 2014 09:40:00 GMT</pubDate><guid>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205798.html</guid><wfw:comment>http://www.cppblog.com/mmdengwo/comments/205798.html</wfw:comment><comments>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205798.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mmdengwo/comments/commentRss/205798.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mmdengwo/services/trackbacks/205798.html</trackback:ping><description><![CDATA[<p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;从Lua 5.1开始，我们可以使用require和module函数来获取和创建Lua中的模块。从使用者的角度来看，一个模块就是一个程序库，可以通过require来加载，之后便得到一个类型为table的全局变量。此时的table就像名字空间一样，可以访问其中的函数和常量，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #ff00ff; line-height: 1.5 !important;">require</span> <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">mod</span><span style="color: #800000; line-height: 1.5 !important;">"</span><br /><span style="color: #008080; line-height: 1.5 !important;">2</span> mod.foo()<br /><span style="color: #008080; line-height: 1.5 !important;">3</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> m2 = <span style="color: #ff00ff; line-height: 1.5 !important;">require</span> <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">mod2</span><span style="color: #800000; line-height: 1.5 !important;">"</span><br /><span style="color: #008080; line-height: 1.5 !important;">4</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> f = mod2.foo<br /><span style="color: #008080; line-height: 1.5 !important;">5</span> f()&nbsp;&nbsp; </pre></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 1. require函数：</span><br />&nbsp;&nbsp; &nbsp;require函数的调用形式为require "模块名"。该调用会返回一个由模块函数组成的table，并且还会定义一个包含该table的全局变量。在使用Lua中的标准库时可以不用显示的调用require，因为Lua已经预先加载了他们。<br />&nbsp;&nbsp; &nbsp;require函数在搜素加载模块时，有一套自定义的模式，如：<br />&nbsp;&nbsp; &nbsp;<span style="color: #0000ff;">?;?.lua;c:/windows/?;/usr/local/lua/?/?.lua</span><br />&nbsp;&nbsp; &nbsp;在上面的模式中，只有问号<strong><span style="color: #0000ff;">(?)</span></strong>和分号<strong><span style="color: #0000ff;">(;)</span></strong>是模式字符，分别表示require函数的参数(模块名)和模式间的分隔符。如：调用require "sql"，将会打开以下的文件：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;sql</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;sql.lua</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;c:/windows/sql</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;/usr/local/lua/sql/sql.lua</span><br />&nbsp;&nbsp; &nbsp;Lua将require搜索的模式字符串放在变量<span style="color: #0000ff;">package.path</span>中。当Lua启动后，便以环境变量<span style="color: #0000ff;">LUA_PATH</span>的值来初始化这个变量。如果没有找到该环境变量，则使用一个编译时定义的默认路径来初始化。如果require无法找到与模块名相符的Lua文件，就会找C程序库。C程序库的搜索模式存放在变量<span style="color: #0000ff;">package.cpath</span>中。而这个变量则是通过环境变量<span style="color: #0000ff;">LUA_CPATH</span>来初始化的。<br />&nbsp;&nbsp;&nbsp;&nbsp;<br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp; &nbsp;2. 编写模块的基本方法：</span><br />&nbsp;&nbsp; &nbsp;见如下代码和关键性注释：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">将模块名设置为require的参数，这样今后重命名模块时，只需重命名文件名即可。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 2</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> modname = ...<br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> M = {}<br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span> <span style="color: #008080; line-height: 1.5 !important;">_G</span>[modname] = M<br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span> <br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span> M.i = {r = <span style="color: #800080; line-height: 1.5 !important;">0</span>, i = <span style="color: #800080; line-height: 1.5 !important;">1</span>}  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">定义一个模块内的常量。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 7</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> M.new(r,i) <span style="color: #0000ff; line-height: 1.5 !important;">return</span> {r = r, i = i} <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> M.add(c1,c2) <br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> M.new(c1.r + c2.r,c1.i + c2.i)<br /><span style="color: #008080; line-height: 1.5 !important;">10</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">11</span> <br /><span style="color: #008080; line-height: 1.5 !important;">12</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> M.sub(c1,c2)<br /><span style="color: #008080; line-height: 1.5 !important;">13</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> M.new(c1.r - c2.r,c1.i - c2.i)<br /><span style="color: #008080; line-height: 1.5 !important;">14</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">15</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">返回和模块对应的table。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">16</span> <span style="color: #0000ff; line-height: 1.5 !important;">return</span> M</pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp;<br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 3. 使用环境：</span><br />&nbsp;&nbsp; &nbsp;仔细阅读上例中的代码，我们可以发现一些细节上问题。比如模块内函数之间的调用仍然要保留模块名的限定符，如果是私有变量还需要加local关键字，同时不能加模块名限定符。如果需要将私有改为公有，或者反之，都需要一定的修改。那又该如何规避这些问题呢？我们可以通过Lua的函数&#8220;全局环境&#8221;来有效的解决这些问题。见如下修改的代码和关键性注释：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">模块设置和初始化。这一点和上例一致。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 2</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> modname = ...<br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> M = {}<br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span> <span style="color: #008080; line-height: 1.5 !important;">_G</span>[modname] = M<br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span> <br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">声明这个模块将会用到的全局函数，因为在setfenv之后将无法再访问他们，</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 7</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">因此需要在设置之前先用本地变量获取。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 8</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> sqrt = mat.sqrt<br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> io = io<br /><span style="color: #008080; line-height: 1.5 !important;">10</span> <br /><span style="color: #008080; line-height: 1.5 !important;">11</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">在这句话之后就不再需要外部访问了。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">12</span> <span style="color: #ff00ff; line-height: 1.5 !important;">setfenv</span>(<span style="color: #800080; line-height: 1.5 !important;">1</span>,M)<br /><span style="color: #008080; line-height: 1.5 !important;">13</span> <br /><span style="color: #008080; line-height: 1.5 !important;">14</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">后面的函数和常量定义都无需模块限定符了。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">15</span> i = {r = <span style="color: #800080; line-height: 1.5 !important;">0</span>, i = <span style="color: #800080; line-height: 1.5 !important;">1</span>}<br /><span style="color: #008080; line-height: 1.5 !important;">16</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> new(r,i) <span style="color: #0000ff; line-height: 1.5 !important;">return</span> {r = r, i = i} <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">17</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> add(c1,c2) <br /><span style="color: #008080; line-height: 1.5 !important;">18</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> new(c1.r + c2.r,c1.i + c2.i)<br /><span style="color: #008080; line-height: 1.5 !important;">19</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">20</span>  <br /><span style="color: #008080; line-height: 1.5 !important;">21</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> sub(c1,c2)<br /><span style="color: #008080; line-height: 1.5 !important;">22</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> new(c1.r - c2.r,c1.i - c2.i)<br /><span style="color: #008080; line-height: 1.5 !important;">23</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">24</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">返回和模块对应的table。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">25</span> <span style="color: #0000ff; line-height: 1.5 !important;">return</span> M</pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 4. module函数：</span><br />&nbsp;&nbsp; &nbsp;在Lua 5.1中，我们可以用module(...)函数来代替以下代码，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> modname = ...<br /><span style="color: #008080; line-height: 1.5 !important;">2</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> M = {}<br /><span style="color: #008080; line-height: 1.5 !important;">3</span> <span style="color: #008080; line-height: 1.5 !important;">_G</span>[modname] = M<br /><span style="color: #008080; line-height: 1.5 !important;">4</span> <span style="color: #ff00ff; line-height: 1.5 !important;">package.loaded</span>[modname] = M<br /><span style="color: #008080; line-height: 1.5 !important;">5</span>     <span style="color: #008000; line-height: 1.5 !important;">--[[</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">6</span> <span style="color: #008000; line-height: 1.5 !important;">    和普通Lua程序块一样声明外部函数。<br /></span><span style="color: #008080; line-height: 1.5 !important;">7</span> <span style="color: #008000; line-height: 1.5 !important;">    --</span><span style="color: #008000; line-height: 1.5 !important;">]]</span><br /><span style="color: #008080; line-height: 1.5 !important;">8</span> <span style="color: #ff00ff; line-height: 1.5 !important;">setfenv</span>(<span style="color: #800080; line-height: 1.5 !important;">1</span>,M)</pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 由于在默认情况下，module不提供外部访问，必须在调用它之前，为需要访问的外部函数或模块声明适当的局部变量。然后Lua提供了一种更为方便的实现方式，即在调用module函数时，多传入一个package.seeall的参数，如：<br />&nbsp;&nbsp; &nbsp;<span style="color: #0000ff;">module(...,package.seeall)</span></p><img src ="http://www.cppblog.com/mmdengwo/aggbug/205798.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mmdengwo/" target="_blank">沛沛</a> 2014-02-17 17:40 <a href="http://www.cppblog.com/mmdengwo/archive/2014/02/17/205798.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Step By Step(Lua环境)</title><link>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205797.html</link><dc:creator>沛沛</dc:creator><author>沛沛</author><pubDate>Mon, 17 Feb 2014 09:39:00 GMT</pubDate><guid>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205797.html</guid><wfw:comment>http://www.cppblog.com/mmdengwo/comments/205797.html</wfw:comment><comments>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205797.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mmdengwo/comments/commentRss/205797.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mmdengwo/services/trackbacks/205797.html</trackback:ping><description><![CDATA[<p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp; Lua将其所有的全局变量保存在一个常规的table中，这个table被称为&#8220;环境&#8221;。它被保存在全局变量<strong><span style="color: #0000ff;">_G</span></strong>中。<br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp; &nbsp;1. 全局变量声明：</span><br />&nbsp;&nbsp; &nbsp;Lua中的全局变量不需要声明就可以使用。尽管很方便，但是一旦出现笔误就会造成难以发现的错误。我们可以通过给_G表加元表的方式来保护全局变量的读取和设置，这样就能降低这种笔误问题的发生几率了。见如下示例代码：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">该table用于存储所有已经声明过的全局变量名</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 2</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> declaredNames = {} <br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> mt = {<br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span>     __newindex = <span style="color: #0000ff; line-height: 1.5 !important;">function</span>(table,name,value)<br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span>         <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">先检查新的名字是否已经声明过，如果存在，这直接通过rawset函数设置即可。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 6</span>         <span style="color: #0000ff; line-height: 1.5 !important;">if</span> <span style="color: #0000ff; line-height: 1.5 !important;">not</span> declaredNames[name] <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span>             <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">再检查本次操作是否是在主程序或者C代码中完成的，如果是，就继续设置，否则报错。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 8</span>             <span style="color: #0000ff; line-height: 1.5 !important;">local</span> w = <span style="color: #ff00ff; line-height: 1.5 !important;">debug.getinfo</span>(<span style="color: #800080; line-height: 1.5 !important;">2</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">S</span><span style="color: #800000; line-height: 1.5 !important;">"</span>).what<br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span>             <span style="color: #0000ff; line-height: 1.5 !important;">if</span> w ~= <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">main</span><span style="color: #800000; line-height: 1.5 !important;">"</span> <span style="color: #0000ff; line-height: 1.5 !important;">and</span> w ~= <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">C</span><span style="color: #800000; line-height: 1.5 !important;">"</span> <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;">10</span>                 <span style="color: #ff00ff; line-height: 1.5 !important;">error</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">attempt to write to undeclared variable </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. name)<br /><span style="color: #008080; line-height: 1.5 !important;">11</span>             <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">12</span>             <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">在实际设置之前，更新一下declaredNames表，下次再设置时就无需检查了。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">13</span>             declaredNames[name] = <span style="color: #0000ff; line-height: 1.5 !important;">true</span><br /><span style="color: #008080; line-height: 1.5 !important;">14</span>         <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">15</span>         <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">Setting </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. name .. <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;"> to </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. value)<br /><span style="color: #008080; line-height: 1.5 !important;">16</span>         <span style="color: #ff00ff; line-height: 1.5 !important;">rawset</span>(table,name,value)<br /><span style="color: #008080; line-height: 1.5 !important;">17</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span>,<br /><span style="color: #008080; line-height: 1.5 !important;">18</span>     <br /><span style="color: #008080; line-height: 1.5 !important;">19</span>     __index = <span style="color: #0000ff; line-height: 1.5 !important;">function</span>(_,name)<br /><span style="color: #008080; line-height: 1.5 !important;">20</span>         <span style="color: #0000ff; line-height: 1.5 !important;">if</span> <span style="color: #0000ff; line-height: 1.5 !important;">not</span> declaredNames[name] <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;">21</span>             <span style="color: #ff00ff; line-height: 1.5 !important;">error</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">attempt to read undeclared variable </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. name)<br /><span style="color: #008080; line-height: 1.5 !important;">22</span>         <span style="color: #0000ff; line-height: 1.5 !important;">else</span><br /><span style="color: #008080; line-height: 1.5 !important;">23</span>             <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #ff00ff; line-height: 1.5 !important;">rawget</span>(_,name)<br /><span style="color: #008080; line-height: 1.5 !important;">24</span>         <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">25</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">26</span> }    <br /><span style="color: #008080; line-height: 1.5 !important;">27</span> <span style="color: #ff00ff; line-height: 1.5 !important;">setmetatable</span>(<span style="color: #008080; line-height: 1.5 !important;">_G</span>,mt)<br /><span style="color: #008080; line-height: 1.5 !important;">28</span> <br /><span style="color: #008080; line-height: 1.5 !important;">29</span> a = <span style="color: #800080; line-height: 1.5 !important;">11</span><br /><span style="color: #008080; line-height: 1.5 !important;">30</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> kk = aa<br /><span style="color: #008080; line-height: 1.5 !important;">31</span> <br /><span style="color: #008080; line-height: 1.5 !important;">32</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出结果为：</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">33</span> <span style="color: #008000; line-height: 1.5 !important;">--[[</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">34</span> <span style="color: #008000; line-height: 1.5 !important;">Setting a to 11<br /></span><span style="color: #008080; line-height: 1.5 !important;">35</span> <span style="color: #008000; line-height: 1.5 !important;">lua: d:/test.lua:21: attempt to read undeclared variable aa<br /></span><span style="color: #008080; line-height: 1.5 !important;">36</span> <span style="color: #008000; line-height: 1.5 !important;">stack traceback:<br /></span><span style="color: #008080; line-height: 1.5 !important;">37</span> <span style="color: #008000; line-height: 1.5 !important;">        [C]: in function 'error'<br /></span><span style="color: #008080; line-height: 1.5 !important;">38</span> <span style="color: #008000; line-height: 1.5 !important;">        d:/test.lua:21: in function &lt;d:/test.lua:19&gt;<br /></span><span style="color: #008080; line-height: 1.5 !important;">39</span> <span style="color: #008000; line-height: 1.5 !important;">        d:/test.lua:30: in main chunk<br /></span><span style="color: #008080; line-height: 1.5 !important;">40</span> <span style="color: #008000; line-height: 1.5 !important;">        [C]: ?<br /></span><span style="color: #008080; line-height: 1.5 !important;">41</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">]]</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 2. 非全局的环境：</span><br />&nbsp;&nbsp; &nbsp;全局环境存在一个刚性的问题，即它的修改将影响到程序的所有部分。Lua 5为此做了一些改进，新的特征可以支持每个函数拥有自己独立的全局环境，而由该函数创建的closure函数将继承该函数的全局变量表。这里我们可以通过setfenv函数来改变一个函数的环境，该函数接受两个参数，一个是函数名，另一个是新的环境table。第一个参数除了函数名本身，还可以指定为一个数字，以表示当前函数调用栈中的层数。数字1表示当前函数，2表示它的调用函数，以此类推。见如下代码：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> a = <span style="color: #800080; line-height: 1.5 !important;">1</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span> <span style="color: #ff00ff; line-height: 1.5 !important;">setfenv</span>(<span style="color: #800080; line-height: 1.5 !important;">1</span>,{})<br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(a)<br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span> <br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出结果为：</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 6</span> <span style="color: #008000; line-height: 1.5 !important;">--[[</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 7</span> <span style="color: #008000; line-height: 1.5 !important;">lua: d:/test.lua:3: attempt to call global 'print' (a nil value)<br /></span><span style="color: #008080; line-height: 1.5 !important;"> 8</span> <span style="color: #008000; line-height: 1.5 !important;">stack traceback:<br /></span><span style="color: #008080; line-height: 1.5 !important;"> 9</span> <span style="color: #008000; line-height: 1.5 !important;">        d:/test.lua:3: in main chunk<br /></span><span style="color: #008080; line-height: 1.5 !important;">10</span> <span style="color: #008000; line-height: 1.5 !important;">        [C]: ?<br /></span><span style="color: #008080; line-height: 1.5 !important;">11</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">]]</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 为什么得到这样的结果呢？因为print和变量a一样，都是全局表中的字段，而新的全局表是空的，所以print调用将会报错。<br />&nbsp;&nbsp;&nbsp; 为了应对这一副作用，我们可以让原有的全局表_G作为新全局表的内部表，在访问已有全局变量时，可以直接转到_G中的字段，而对于新的全局字段，则保留在新的全局表中。这样即便是函数中的误修改，也不会影响到其他用到全局变量(_G)的地方。见如下代码：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> a = <span style="color: #800080; line-height: 1.5 !important;">1</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> newgt = {}  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">新环境表</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 3</span> <span style="color: #ff00ff; line-height: 1.5 !important;">setmetatable</span>(newgt,{__index = <span style="color: #008080; line-height: 1.5 !important;">_G</span>})<br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span> <span style="color: #ff00ff; line-height: 1.5 !important;">setfenv</span>(<span style="color: #800080; line-height: 1.5 !important;">1</span>,newgt)<br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(a)  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出1</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 6</span> <br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span> a = <span style="color: #800080; line-height: 1.5 !important;">10</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(a)  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出10</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 9</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #008080; line-height: 1.5 !important;">_G</span>.a) <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出1</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">10</span> <span style="color: #008080; line-height: 1.5 !important;">_G</span>.a = <span style="color: #800080; line-height: 1.5 !important;">20</span><br /><span style="color: #008080; line-height: 1.5 !important;">11</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(a)  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出10</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 最后给出的示例是函数环境变量的继承性。见如下代码：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> factory()<br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span>() <span style="color: #0000ff; line-height: 1.5 !important;">return</span> a <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span> a = <span style="color: #800080; line-height: 1.5 !important;">3</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span> f1 = factory()<br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span> f2 = factory()<br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(f1())  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出3</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 8</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(f2())  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出3</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 9</span> <br /><span style="color: #008080; line-height: 1.5 !important;">10</span> <span style="color: #ff00ff; line-height: 1.5 !important;">setfenv</span>(f1,{a = <span style="color: #800080; line-height: 1.5 !important;">10</span>})<br /><span style="color: #008080; line-height: 1.5 !important;">11</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(f1())  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出10</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">12</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(f2())  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出3</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><img src ="http://www.cppblog.com/mmdengwo/aggbug/205797.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mmdengwo/" target="_blank">沛沛</a> 2014-02-17 17:39 <a href="http://www.cppblog.com/mmdengwo/archive/2014/02/17/205797.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Step By Step(Lua元表与元方法)</title><link>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205796.html</link><dc:creator>沛沛</dc:creator><author>沛沛</author><pubDate>Mon, 17 Feb 2014 09:39:00 GMT</pubDate><guid>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205796.html</guid><wfw:comment>http://www.cppblog.com/mmdengwo/comments/205796.html</wfw:comment><comments>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205796.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mmdengwo/comments/commentRss/205796.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mmdengwo/services/trackbacks/205796.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;Lua中提供的元表是用于帮助Lua数据变量完成某些非预定义功能的个性化行为，如两个table的相加。假设a和b都是table，通过元表可以定义如何计算表达式a+b。当Lua试图将两个table相加时，它会先检查两者之一是否有元表，然后检查该元表中是否存在__add字段，如果有，就调用该字段对应的值。这个值就是所谓的&#8220;元方法&#8221;，这个函数用于计算table的和。&n...&nbsp;&nbsp;<a href='http://www.cppblog.com/mmdengwo/archive/2014/02/17/205796.html'>阅读全文</a><img src ="http://www.cppblog.com/mmdengwo/aggbug/205796.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mmdengwo/" target="_blank">沛沛</a> 2014-02-17 17:39 <a href="http://www.cppblog.com/mmdengwo/archive/2014/02/17/205796.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Step By Step(Lua数据持久化)</title><link>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205795.html</link><dc:creator>沛沛</dc:creator><author>沛沛</author><pubDate>Mon, 17 Feb 2014 09:38:00 GMT</pubDate><guid>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205795.html</guid><wfw:comment>http://www.cppblog.com/mmdengwo/comments/205795.html</wfw:comment><comments>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205795.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mmdengwo/comments/commentRss/205795.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mmdengwo/services/trackbacks/205795.html</trackback:ping><description><![CDATA[<p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><span style="color: #800080; font-size: 15px;">&nbsp; 1. 数据文件：</span><br />&nbsp;&nbsp; &nbsp;我们可以利用Lua中table的构造式来定义一种文件格式，即文件中的数据是table构造并初始化的代码，这种方式对于Lua程序而言是非常方便和清晰的，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;Entry { "Stephen Liu", "Male", "Programmer", "BS" }</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;Entry { "Jerry Tian", "Male", "Programmer", "BS" }</span><br />&nbsp;&nbsp; &nbsp;需要注意的是，Entry{&lt;code&gt;}等价于Entry({&lt;code&gt;})，对于上面的数据条目，如果我们能够定义一个合适的Entry函数，就可以让这些数据成为我们Lua代码的一部分了。见如下代码及其注释：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> count = <span style="color: #800080; line-height: 1.5 !important;">0</span><br /><span style="color: #008080; line-height: 1.5 !important;">2</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">这里预先定义了Entry函数，以便在执行dofile中的数据代码时，可以找到匹配的该函数。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">3</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> Entry() count = count + <span style="color: #800080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">4</span> <span style="color: #ff00ff; line-height: 1.5 !important;">dofile</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">d:/lua_data.conf</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">5</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">number of entries: </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. count)<br /><span style="color: #008080; line-height: 1.5 !important;">6</span> <br /><span style="color: #008080; line-height: 1.5 !important;">7</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出结果为：</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">8</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">number of entries: 2</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 相比于上面数据文件的格式，我们还可以定义一种更为清晰的&#8220;自描述的数据&#8221;格式，其中每项数据都伴随一个表示其含义的简短描述。采用这样的格式，即便今后数据项发生了变化，我们仍然可以在改动极小的情况下保持向后的兼容性。见如下数据格式和相关的代码：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;Entry { name = "Stephen Liu", gender = "Male", job = "Programmer", education = "BS" }</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;Entry { name = "Jerry Tian", gender = "Male", job = "Programmer", education = "BS" }</span></p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> personInfo = {}<br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> Entry(b) <br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span>     <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">这里将table对象b的name字段值作为personInfo的key信息。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 4</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span> b.name <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span>         personInfo[b.name] = <span style="color: #0000ff; line-height: 1.5 !important;">true</span> <br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span> <br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span> <span style="color: #ff00ff; line-height: 1.5 !important;">dofile</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">d:/lua_data.conf</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">10</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> name <span style="color: #0000ff; line-height: 1.5 !important;">in</span> <span style="color: #ff00ff; line-height: 1.5 !important;">pairs</span>(personInfo) <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">11</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(name)<br /><span style="color: #008080; line-height: 1.5 !important;">12</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">13</span> <br /><span style="color: #008080; line-height: 1.5 !important;">14</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出结果为：</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">15</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">Jerry Tian</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">16</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">Stephen Liu</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 可以看出这些代码片段都采用了事件驱动的做法。Entry函数作为一个回调函数，在执行dofile时为数据文件中的每个条目所调用。<br />&nbsp;&nbsp; &nbsp;Lua不仅运行速度快，而且编译速度也快。这主要是因为Lua在设计之初就将数据描述作为Lua的主要应用之一所致。<br />&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp; &nbsp;<span style="color: #800080; font-size: 15px;">2. 序列化：</span><br />&nbsp;&nbsp;&nbsp; 相信有Java或C#开发经验的人对于这一术语并不陌生。就是将数据对象转换为字节流后在通过IO输出到文件或网络，读取的时候再将这些数据重新构造为与原始对象具有相同值的新对象。或者我们也可以将一段可执行的Lua代码作为序列化后的数据格式。比如：varname = &lt;expr&gt;，这里的&lt;expr&gt;表示计算变量varname的表达式。下面的示例代码用于序列化无环的table：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> serialize(o)<br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span> <span style="color: #ff00ff; line-height: 1.5 !important;">type</span>(o) == <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">number</span><span style="color: #800000; line-height: 1.5 !important;">"</span> <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span>         <span style="color: #ff00ff; line-height: 1.5 !important;">io.write</span>(o)<br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span>     <span style="color: #0000ff; line-height: 1.5 !important;">elseif</span> <span style="color: #ff00ff; line-height: 1.5 !important;">type</span>(o) == <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">string</span><span style="color: #800000; line-height: 1.5 !important;">"</span> <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span>         <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">string.format函数的"%q"参数可以转义字符串中的元字符。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 6</span>         <span style="color: #ff00ff; line-height: 1.5 !important;">io.write</span>(<span style="color: #ff00ff; line-height: 1.5 !important;">string.format</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">%q</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,o)) <br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span>     <span style="color: #0000ff; line-height: 1.5 !important;">elseif</span> <span style="color: #ff00ff; line-height: 1.5 !important;">type</span>(o) == <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">table</span><span style="color: #800000; line-height: 1.5 !important;">"</span> <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span>         <span style="color: #ff00ff; line-height: 1.5 !important;">io.write</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">{\n</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span>         <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">迭代table中的各个元素，同时递归的写出各个字段的value。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">10</span>         <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">由此可以看出，这个简单例子可以支持嵌套的table。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">11</span>         <span style="color: #0000ff; line-height: 1.5 !important;">for</span> k,v <span style="color: #0000ff; line-height: 1.5 !important;">in</span> <span style="color: #ff00ff; line-height: 1.5 !important;">pairs</span>(o) <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">12</span>             <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">这样做是为了防止k中包含非法的Lua标识符。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">13</span>             <span style="color: #ff00ff; line-height: 1.5 !important;">io.write</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;"> [</span><span style="color: #800000; line-height: 1.5 !important;">"</span>); serialize(k); <span style="color: #ff00ff; line-height: 1.5 !important;">io.write</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">] = </span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">14</span>             serialize(v)<br /><span style="color: #008080; line-height: 1.5 !important;">15</span>             <span style="color: #ff00ff; line-height: 1.5 !important;">io.write</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">,\n</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">16</span>         <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">17</span>         <span style="color: #ff00ff; line-height: 1.5 !important;">io.write</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">}\n</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">18</span>     <span style="color: #0000ff; line-height: 1.5 !important;">else</span><br /><span style="color: #008080; line-height: 1.5 !important;">19</span>         <span style="color: #ff00ff; line-height: 1.5 !important;">error</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">cannot serialize a </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. <span style="color: #ff00ff; line-height: 1.5 !important;">type</span>(o))<br /><span style="color: #008080; line-height: 1.5 !important;">20</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">21</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><img src ="http://www.cppblog.com/mmdengwo/aggbug/205795.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mmdengwo/" target="_blank">沛沛</a> 2014-02-17 17:38 <a href="http://www.cppblog.com/mmdengwo/archive/2014/02/17/205795.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Step By Step(Lua数据结构)</title><link>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205794.html</link><dc:creator>沛沛</dc:creator><author>沛沛</author><pubDate>Mon, 17 Feb 2014 09:38:00 GMT</pubDate><guid>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205794.html</guid><wfw:comment>http://www.cppblog.com/mmdengwo/comments/205794.html</wfw:comment><comments>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205794.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mmdengwo/comments/commentRss/205794.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mmdengwo/services/trackbacks/205794.html</trackback:ping><description><![CDATA[<p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;Lua中的table不是一种简单的数据结构，它可以作为其它数据结构的基础。如数组、记录、线性表、队列和集合等，在Lua中都可以通过table来表示。<span style="color: #800080; font-size: 15px;">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp; 1. 数组：</span><br />&nbsp;&nbsp; &nbsp;使用整数来索引table即可在Lua中实现数组。因此，Lua中的数组没有固定的大小，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> a = {}<br /><span style="color: #008080; line-height: 1.5 !important;">2</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> i = <span style="color: #800080; line-height: 1.5 !important;">1</span>, <span style="color: #800080; line-height: 1.5 !important;">1000</span> <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">3</span>     a[i] = <span style="color: #800080; line-height: 1.5 !important;">0</span><br /><span style="color: #008080; line-height: 1.5 !important;">4</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">5</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">The length of array 'a' is </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. #a)<br /><span style="color: #008080; line-height: 1.5 !important;">6</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">The length of array 'a' is 1000</span></pre></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 在Lua中，可以让任何数作为数组的起始索引，但通常而言，都会使用1作为其起始索引值。而且很多Lua的内置功能和函数都依赖这一特征，因此在没有充分理由的前提下，尽量保证这一规则。下面的方法是通过table的构造器来创建并初始化一个数组的，如：<br />&nbsp;&nbsp; &nbsp;<span style="color: #0000ff;">squares = {1, 4, 9, 16, 25}</span><br /><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 2. 二维数组：</span><br />&nbsp;&nbsp; &nbsp;在Lua中我们可以通过两种方式来利用table构造多维数组。其中，第一种方式通过&#8220;数组的数组&#8221;的方式来实现多维数组的，即在一维数组上的每个元素也同样为table对象，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> mt = {}<br /><span style="color: #008080; line-height: 1.5 !important;">2</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> i = <span style="color: #800080; line-height: 1.5 !important;">1</span>, N <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">3</span>     mt[i] = {}<br /><span style="color: #008080; line-height: 1.5 !important;">4</span>     <span style="color: #0000ff; line-height: 1.5 !important;">for</span> j = <span style="color: #800080; line-height: 1.5 !important;">1</span>, M <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">5</span>         mt[i][j] = i * j<br /><span style="color: #008080; line-height: 1.5 !important;">6</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">7</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 第二种方式是将二维数组的索引展开，并以固定的常量作为第二维度的步长，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> mt = {}<br /><span style="color: #008080; line-height: 1.5 !important;">2</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> i = <span style="color: #800080; line-height: 1.5 !important;">1</span>, N <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">3</span>     <span style="color: #0000ff; line-height: 1.5 !important;">for</span> j = <span style="color: #800080; line-height: 1.5 !important;">1</span>, M <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">4</span>         mt[(i - <span style="color: #800080; line-height: 1.5 !important;">1</span>) * M + j] = i * j<br /><span style="color: #008080; line-height: 1.5 !important;">5</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">6</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 3. 链表：</span><br />&nbsp;&nbsp; &nbsp;由于table是动态的实体，所以在Lua中实现链表是很方便的。其中，每个结点均以table来表示，一个&#8220;链接&#8221;只是结点中的一个字段，该字段包含对其它table的引用，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> list = <span style="color: #0000ff; line-height: 1.5 !important;">nil</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> i = <span style="color: #800080; line-height: 1.5 !important;">1</span>, <span style="color: #800080; line-height: 1.5 !important;">10</span> <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span>     list = { <span style="color: #ff00ff; line-height: 1.5 !important;">next</span> = list, value = i}<br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span> <br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> l = list<br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span> <span style="color: #0000ff; line-height: 1.5 !important;">while</span> l <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(l.value)<br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span>     l = l.<span style="color: #ff00ff; line-height: 1.5 !important;">next</span><br /><span style="color: #008080; line-height: 1.5 !important;">10</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 4. 队列与双向队列：</span><br />&nbsp;&nbsp; &nbsp;在Lua中实现队列的简单方法是使用table库函数insert和remove。但是由于这种方法会导致后续元素的移动，因此当队列的数据量较大时，不建议使用该方法。下面的代码是一种更高效的实现方式，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> List = {}<br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span> <br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> List.new()<br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> {first = <span style="color: #800080; line-height: 1.5 !important;">0</span>, last = -<span style="color: #800080; line-height: 1.5 !important;">1</span>}<br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span> <br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> List.pushFront(list, value)<br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> first = list.first - <span style="color: #800080; line-height: 1.5 !important;">1</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span>     list.first = first<br /><span style="color: #008080; line-height: 1.5 !important;">10</span>     list[first] = value<br /><span style="color: #008080; line-height: 1.5 !important;">11</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">12</span> <br /><span style="color: #008080; line-height: 1.5 !important;">13</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> List.pushBack(list, value)<br /><span style="color: #008080; line-height: 1.5 !important;">14</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> last = list.last + <span style="color: #800080; line-height: 1.5 !important;">1</span><br /><span style="color: #008080; line-height: 1.5 !important;">15</span>     list.last = last<br /><span style="color: #008080; line-height: 1.5 !important;">16</span>     list[last] = value<br /><span style="color: #008080; line-height: 1.5 !important;">17</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">18</span> <br /><span style="color: #008080; line-height: 1.5 !important;">19</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> List.popFront(list)<br /><span style="color: #008080; line-height: 1.5 !important;">20</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> first = list.first<br /><span style="color: #008080; line-height: 1.5 !important;">21</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span> first &gt; list.last <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;">22</span>         <span style="color: #ff00ff; line-height: 1.5 !important;">error</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">List is empty</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">23</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">24</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> value = list[first]<br /><span style="color: #008080; line-height: 1.5 !important;">25</span>     list[first] = <span style="color: #0000ff; line-height: 1.5 !important;">nil</span><br /><span style="color: #008080; line-height: 1.5 !important;">26</span>     list.first = first + <span style="color: #800080; line-height: 1.5 !important;">1</span><br /><span style="color: #008080; line-height: 1.5 !important;">27</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> value<br /><span style="color: #008080; line-height: 1.5 !important;">28</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">29</span> <br /><span style="color: #008080; line-height: 1.5 !important;">30</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> List.popBack(list)<br /><span style="color: #008080; line-height: 1.5 !important;">31</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> last = list.last<br /><span style="color: #008080; line-height: 1.5 !important;">32</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span> list.first &gt; last <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;">33</span>         <span style="color: #ff00ff; line-height: 1.5 !important;">error</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">List is empty</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">34</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">35</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> value = list[last]<br /><span style="color: #008080; line-height: 1.5 !important;">36</span>     list[last] = <span style="color: #0000ff; line-height: 1.5 !important;">nil</span><br /><span style="color: #008080; line-height: 1.5 !important;">37</span>     list.last = last - <span style="color: #800080; line-height: 1.5 !important;">1</span><br /><span style="color: #008080; line-height: 1.5 !important;">38</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> value<br /><span style="color: #008080; line-height: 1.5 !important;">39</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 5. 集合和包(Bag)：</span><br />&nbsp;&nbsp; &nbsp;在Lua中用table实现集合是非常简单的，见如下代码：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;reserved = { ["while"] = true, ["end"] = true, ["function"] = true, }</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;if not reserved["while"] then</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;--do something</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;end</span><br />&nbsp;&nbsp; &nbsp;在Lua中我们可以将包(Bag)看成MultiSet，与普通集合不同的是该容器中允许key相同的元素在容器中多次出现。下面的代码通过为table中的元素添加计数器的方式来模拟实现该数据结构，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> insert(bag, element)<br /><span style="color: #008080; line-height: 1.5 !important;">2</span>     bag[element] = (bag[element] <span style="color: #0000ff; line-height: 1.5 !important;">or</span> <span style="color: #800080; line-height: 1.5 !important;">0</span>) + <span style="color: #800080; line-height: 1.5 !important;">1</span><br /><span style="color: #008080; line-height: 1.5 !important;">3</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">4</span> <br /><span style="color: #008080; line-height: 1.5 !important;">5</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> remove(bag, element)<br /><span style="color: #008080; line-height: 1.5 !important;">6</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> count = bag[element]<br /><span style="color: #008080; line-height: 1.5 !important;">7</span>     bag[element] = (count <span style="color: #0000ff; line-height: 1.5 !important;">and</span> count &gt; <span style="color: #800080; line-height: 1.5 !important;">1</span>) <span style="color: #0000ff; line-height: 1.5 !important;">and</span> count - <span style="color: #800080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">or</span> <span style="color: #0000ff; line-height: 1.5 !important;">nil</span><br /><span style="color: #008080; line-height: 1.5 !important;">8</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 6. StringBuilder：</span><br />&nbsp;&nbsp; &nbsp;如果想在Lua中将多个字符串连接成为一个大字符串的话，可以通过如下方式实现，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> buff = <span style="color: #800000; line-height: 1.5 !important;">""</span><br /><span style="color: #008080; line-height: 1.5 !important;">2</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> line <span style="color: #0000ff; line-height: 1.5 !important;">in</span> <span style="color: #ff00ff; line-height: 1.5 !important;">io.lines</span>() <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">3</span>     buff = buff .. line .. <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">\n</span><span style="color: #800000; line-height: 1.5 !important;">"</span><br /><span style="color: #008080; line-height: 1.5 !important;">4</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 上面的代码确实可以正常的完成工作，然而当行数较多时，这种方法将会导致大量的内存重新分配和内存间的数据拷贝，由此而带来的性能开销也是相当可观的。事实上，在很多编程语言中String都是不可变对象，如Java，因此如果通过该方式多次连接较大字符串时，均会导致同样的性能问题。为了解决该问题，Java中提供了StringBuilder类，而Lua中则可以利用table的concat方法来解决这一问题，见如下代码：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> t = {}<br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> line <span style="color: #0000ff; line-height: 1.5 !important;">in</span> <span style="color: #ff00ff; line-height: 1.5 !important;">io.lines</span>() <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span>     t[#t + <span style="color: #800080; line-height: 1.5 !important;">1</span>] = line .. <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">\n</span><span style="color: #800000; line-height: 1.5 !important;">"</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> s = <span style="color: #ff00ff; line-height: 1.5 !important;">table.concat</span>(t)<br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span> <br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">concat方法可以接受两个参数，因此上面的方式还可以改为：</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 8</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> t = {}<br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> line <span style="color: #0000ff; line-height: 1.5 !important;">in</span> <span style="color: #ff00ff; line-height: 1.5 !important;">io.lines</span>() <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">10</span>     t[#t + <span style="color: #800080; line-height: 1.5 !important;">1</span>] = line<br /><span style="color: #008080; line-height: 1.5 !important;">11</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">12</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> s = <span style="color: #ff00ff; line-height: 1.5 !important;">table.concat</span>(t,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">\n</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)</pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><img src ="http://www.cppblog.com/mmdengwo/aggbug/205794.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mmdengwo/" target="_blank">沛沛</a> 2014-02-17 17:38 <a href="http://www.cppblog.com/mmdengwo/archive/2014/02/17/205794.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Step By Step(Lua编译执行与错误)</title><link>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205793.html</link><dc:creator>沛沛</dc:creator><author>沛沛</author><pubDate>Mon, 17 Feb 2014 09:37:00 GMT</pubDate><guid>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205793.html</guid><wfw:comment>http://www.cppblog.com/mmdengwo/comments/205793.html</wfw:comment><comments>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205793.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mmdengwo/comments/commentRss/205793.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mmdengwo/services/trackbacks/205793.html</trackback:ping><description><![CDATA[<p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><span style="color: #800080; font-size: 15px;">1. 编译：</span><br />&nbsp;&nbsp; &nbsp;Lua中提供了<strong><span style="color: #0000ff;">dofile</span></strong>函数，它是一种内置的操作，用于运行Lua代码块。但实际上dofile只是一个辅助函数，<strong><span style="color: #0000ff;">loadfile</span></strong>才是真正的核心函数。相比于dofile，loadfile只是从指定的文件中加载Lua代码块，然后编译这段代码块，如果有编译错误，就返回nil，同时给出错误信息，但是在编译成功后并不真正的执行这段代码块。因此，我们可以将dofile实现为：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> <span style="color: #ff00ff; line-height: 1.5 !important;">dofile</span>(filename)<br /><span style="color: #008080; line-height: 1.5 !important;">2</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> f = <span style="color: #ff00ff; line-height: 1.5 !important;">assert</span>(<span style="color: #ff00ff; line-height: 1.5 !important;">loadfile</span>(filename))<br /><span style="color: #008080; line-height: 1.5 !important;">3</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> f()<br /><span style="color: #008080; line-height: 1.5 !important;">4</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 这里如果loadfile执行失败，assert函数将直接引发一个错误。通过dofile的代码，我们还可以看出，如果打算多次运行一个文件中的Lua代码块，我们可以只执行loadfile一次，之后多次运行它返回的结果即可，这样就可以节省多次编译所带来的开销。这一点也是loadfile和dofile在性能上的区别。<br />&nbsp;&nbsp; &nbsp;Lua中还提供了另外一种动态执行Lua代码的方式，即<strong><span style="color: #0000ff;">loadstring</span></strong>函数。顾名思义，相比于loadfile，loadstring的代码源来自于其参数中的字符串，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;f = loadstring("i = i + 1")</span><br />&nbsp;&nbsp; &nbsp;此时f就变成了一个函数，每次调用时就执行"i = i + 1"，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> i = <span style="color: #800080; line-height: 1.5 !important;">0</span><br /><span style="color: #008080; line-height: 1.5 !important;">2</span> f()  <br /><span style="color: #008080; line-height: 1.5 !important;">3</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(i) <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">将输出1</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">4</span> f()<br /><span style="color: #008080; line-height: 1.5 !important;">5</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(i) <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">将输出2</span></pre></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; loadstring确实是一个功能强大的函数，但是由此而换来的性能开销也是我们不得不考虑的事情。所以对于很多常量字符串如果仍然使用loadstring方式，那就没有太大意义了，如上面的例子f = loadstring("i = i + 1")，因为我们完全可以通过f = function () i = i + 1 end的形式取而代之。而后者的执行效率要远远高于前者。毕竟后者只编译一次，而前者则在每次调用loadstring时均被编译。对于loadstring，我们还需要注意的是，该函数总是在全局环境中编译它的字符串，因此它将无法文件局部变量，而是只能访问全局变量，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> i = <span style="color: #800080; line-height: 1.5 !important;">32</span><br /><span style="color: #008080; line-height: 1.5 !important;">2</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> i = <span style="color: #800080; line-height: 1.5 !important;">0</span><br /><span style="color: #008080; line-height: 1.5 !important;">3</span> f = <span style="color: #ff00ff; line-height: 1.5 !important;">loadstring</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">i = i + 1; print(i)</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">4</span> g = <span style="color: #0000ff; line-height: 1.5 !important;">function</span>() i = i + <span style="color: #800080; line-height: 1.5 !important;">1</span>; <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(i) <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">5</span> f()   <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">f函数中的i为全局变量i，因此输出33</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">6</span> g()   <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">g函数中的i为局部变量i，因此输出1</span></pre></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 对于loadstring返回的函数，如果需要对一个表达式求值，则必须在其之前添加return，这样才能构成一条语句，返回表达式的值，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> i = <span style="color: #800080; line-height: 1.5 !important;">32</span><br /><span style="color: #008080; line-height: 1.5 !important;">2</span> f = <span style="color: #ff00ff; line-height: 1.5 !important;">loadstring</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">i = i + 1; return i * 2</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">3</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(f()) <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出66</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">4</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(f()) <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出68。由于loadstring返回的就是正规的函数，因此可以被反复调用。</span></pre></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; Lua将所有独立的程序块视为一个匿名函数的函数体，并且该匿名函数还具有可变长实参，因此在调用loadstring时，可以为其传递参数，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> i = <span style="color: #800080; line-height: 1.5 !important;">30</span><br /><span style="color: #008080; line-height: 1.5 !important;">2</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">下面的...表示变长实参，将值赋给局部变量x。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">3</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> f = <span style="color: #ff00ff; line-height: 1.5 !important;">assert</span>(<span style="color: #ff00ff; line-height: 1.5 !important;">loadstring</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">local x = ...; return (x + 10)    * 2</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)) <br /><span style="color: #008080; line-height: 1.5 !important;">4</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> i = <span style="color: #800080; line-height: 1.5 !important;">1</span>, <span style="color: #800080; line-height: 1.5 !important;">20</span> <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">5</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #ff00ff; line-height: 1.5 !important;">string.rep</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">*</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,f(i)))<br /><span style="color: #008080; line-height: 1.5 !important;">6</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 2. C代码：</span><br />&nbsp;&nbsp; &nbsp;上一小节介绍的是动态加载Lua代码，而事实上，Lua本身也支持动态加载C动态库中的代码，要完成该操作，我们需要借助于Lua内置的系统函数<strong><span style="color: #0000ff;">package.loadlib</span></strong>。该函数有两个字符串参数，分别是动态库的全文件名和该库包含的函数名称，典型的调用代码如下：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;local path = "/usr/local/lib/test.so"</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;local f = package.loadlib(path,"test_func")</span><br />&nbsp;&nbsp; &nbsp;由于loadlib是非常底层的函数，因为在调用时必须提供完整的路径名和函数名称。<br /><br />&nbsp;<span style="color: #800080; font-size: 15px;">&nbsp;&nbsp; 3. 错误：</span><br />&nbsp;&nbsp; &nbsp;Lua作为一种嵌入式脚本语言，在发生错误时，不应该只是简单的退出或崩溃。相反，一旦有错误发生，Lua就应该结束当前程序块并返回到应用程序。<br />&nbsp;&nbsp; &nbsp;在Lua中我们可以通过error()函数获取错误消息，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;print "enter a number:"</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;n = io.read("*number")</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;if not n then error("invalid input") end</span><br />&nbsp;&nbsp; &nbsp;上面代码中的最后一行我们可以通过Lua提供的另外一个内置函数assert类辅助完成，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;print "enter a number:"</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;n = assert(io.read("*number"),"invalid input")</span><br />&nbsp;&nbsp; &nbsp;assert函数将检查其第一个参数是否为true，如果是，则简单的返回该参数，否则就引发一个错误。第二个参数是可选字符串。<br />&nbsp;&nbsp; &nbsp;对于所有的编程语言而言，错误处理都是一个非常重要的环节。在实际的开发中，没有统一的指导原则，只能是在遇到问题后，经过缜密的分析在结合当时的应用场景，最后结合自己的经验再给出错误的具体处理方式。在有些情况下，我们可以直接返回错误码，而在另外一些情况下，则需要直接抛出错误，让开发者能够快速定位导致错误的代码源。<br /><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 4. 错误处理与异常：</span><br />&nbsp;&nbsp; &nbsp;Lua提供了错误处理函数pcall，该函数的第一个参数为需要&#8220;保护执行&#8221;的函数，如果该函数执行失败，pcall将返回false及错误信息，否则返回true和函数调用的返回值。见如下代码：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> foo()<br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> a = <span style="color: #800080; line-height: 1.5 !important;">10</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(a[<span style="color: #800080; line-height: 1.5 !important;">2</span>])<br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span> <br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span> r, msg = <span style="color: #ff00ff; line-height: 1.5 !important;">pcall</span>(foo)<br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span> <span style="color: #0000ff; line-height: 1.5 !important;">if</span> r <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">This is ok.</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span> <span style="color: #0000ff; line-height: 1.5 !important;">else</span><br /><span style="color: #008080; line-height: 1.5 !important;">10</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">This is error.</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">11</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(msg)<br /><span style="color: #008080; line-height: 1.5 !important;">12</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">13</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出结果为：</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">14</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">This is error.</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">15</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">d:/test.lua:3: attempt to index local 'a' (a number value)</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 我们也可以给pcall函数直接传递匿名函数，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> r, msg = <span style="color: #ff00ff; line-height: 1.5 !important;">pcall</span>(<span style="color: #0000ff; line-height: 1.5 !important;">function</span>() <span style="color: #ff00ff; line-height: 1.5 !important;">error</span>({code = <span style="color: #800080; line-height: 1.5 !important;">121</span>}) <span style="color: #0000ff; line-height: 1.5 !important;">end</span>)<br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span> <span style="color: #0000ff; line-height: 1.5 !important;">if</span> r <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">This is ok.</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span> <span style="color: #0000ff; line-height: 1.5 !important;">else</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">This is error.</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(msg.code)<br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出结果为：</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 9</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">This is error.</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">10</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">121</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 5. 错误消息与追溯：</span><br />&nbsp;&nbsp; &nbsp;通常在错误发生时，希望得到更多的调试信息，而不是只有发生错误的位置。至少等追溯到发生错误时和函数调用情况，显示一个完整的函数调用栈轨迹。要完成这一功能，我们需要使用Lua提供的另外一个内置函数<strong><span style="color: #0000ff;">xpcall</span></strong>。该函数除了接受一个需要被调用的函数之外，还接受第二个参数，即错误处理函数。当发生错误时，Lua会在调用栈展开前调用错误处理函数。这样，我们就可以在这个函数中使用debug库的<strong><span style="color: #0000ff;">debug.traceback</span></strong>函数，它会根据调用栈来构建一个扩展的错误消息。如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> errorFunc()<br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> a = <span style="color: #800080; line-height: 1.5 !important;">20</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(a[<span style="color: #800080; line-height: 1.5 !important;">10</span>])<br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span> <br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> errorHandle()<br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #ff00ff; line-height: 1.5 !important;">debug.traceback</span>())<br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span> <br /><span style="color: #008080; line-height: 1.5 !important;">10</span> <span style="color: #0000ff; line-height: 1.5 !important;">if</span> <span style="color: #ff00ff; line-height: 1.5 !important;">xpcall</span>(errorFunc,errorHandle) <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;">11</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">This is OK.</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">12</span> <span style="color: #0000ff; line-height: 1.5 !important;">else</span><br /><span style="color: #008080; line-height: 1.5 !important;">13</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">This is error.</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">14</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">15</span> <br /><span style="color: #008080; line-height: 1.5 !important;">16</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出结果为：</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">17</span> <span style="color: #008000; line-height: 1.5 !important;">--[[</span><span style="color: #008000; line-height: 1.5 !important;">stack traceback:<br /></span><span style="color: #008080; line-height: 1.5 !important;">18</span> <span style="color: #008000; line-height: 1.5 !important;">        d:/test.lua:7: in function &lt;d:/test.lua:6&gt;<br /></span><span style="color: #008080; line-height: 1.5 !important;">19</span> <span style="color: #008000; line-height: 1.5 !important;">        d:/test.lua:3: in function &lt;d:/test.lua:1&gt;<br /></span><span style="color: #008080; line-height: 1.5 !important;">20</span> <span style="color: #008000; line-height: 1.5 !important;">        [C]: in function 'xpcall'<br /></span><span style="color: #008080; line-height: 1.5 !important;">21</span> <span style="color: #008000; line-height: 1.5 !important;">        d:/test.lua:10: in main chunk<br /></span><span style="color: #008080; line-height: 1.5 !important;">22</span> <span style="color: #008000; line-height: 1.5 !important;">        [C]: ?<br /></span><span style="color: #008080; line-height: 1.5 !important;">23</span> <span style="color: #008000; line-height: 1.5 !important;">This is error.<br /></span><span style="color: #008080; line-height: 1.5 !important;">24</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">]]</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><img src ="http://www.cppblog.com/mmdengwo/aggbug/205793.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mmdengwo/" target="_blank">沛沛</a> 2014-02-17 17:37 <a href="http://www.cppblog.com/mmdengwo/archive/2014/02/17/205793.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Step By Step(Lua迭代器和泛型for)</title><link>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205792.html</link><dc:creator>沛沛</dc:creator><author>沛沛</author><pubDate>Mon, 17 Feb 2014 09:36:00 GMT</pubDate><guid>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205792.html</guid><wfw:comment>http://www.cppblog.com/mmdengwo/comments/205792.html</wfw:comment><comments>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205792.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mmdengwo/comments/commentRss/205792.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mmdengwo/services/trackbacks/205792.html</trackback:ping><description><![CDATA[<p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><span style="color: #800080; font-size: 15px;">1. 迭代器与Closure：</span><br />&nbsp;&nbsp; &nbsp;在Lua中，迭代器通常为函数，每调用一次函数，即返回集合中的&#8220;下一个&#8221;元素。每个迭代器都需要在每次成功调用之间保持一些状态，这样才能知道它所在的位置和下一次遍历时的位置。从这一点看，Lua中closure机制为此问题提供了语言上的保障，见如下示例：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> values(t)<br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> i = <span style="color: #800080; line-height: 1.5 !important;">0</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span>()<br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span>         i = i + <span style="color: #800080; line-height: 1.5 !important;">1</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span>         <span style="color: #0000ff; line-height: 1.5 !important;">return</span> t[i]<br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span> t = {<span style="color: #800080; line-height: 1.5 !important;">10</span>, <span style="color: #800080; line-height: 1.5 !important;">20</span>, <span style="color: #800080; line-height: 1.5 !important;">30</span>}<br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span> it = values(t)<br /><span style="color: #008080; line-height: 1.5 !important;">10</span> <span style="color: #0000ff; line-height: 1.5 !important;">while</span> <span style="color: #0000ff; line-height: 1.5 !important;">true</span> <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">11</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> element = it()<br /><span style="color: #008080; line-height: 1.5 !important;">12</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span> element == <span style="color: #0000ff; line-height: 1.5 !important;">nil</span> <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;">13</span>         <span style="color: #0000ff; line-height: 1.5 !important;">break</span><br /><span style="color: #008080; line-height: 1.5 !important;">14</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">15</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(element)<br /><span style="color: #008080; line-height: 1.5 !important;">16</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">17</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">另外一种基于foreach的调用方式(泛型for)</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">18</span> t2 = {<span style="color: #800080; line-height: 1.5 !important;">15</span>, <span style="color: #800080; line-height: 1.5 !important;">25</span>, <span style="color: #800080; line-height: 1.5 !important;">35</span>}<br /><span style="color: #008080; line-height: 1.5 !important;">19</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> element <span style="color: #0000ff; line-height: 1.5 !important;">in</span> values(t2) <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">20</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(element)<br /><span style="color: #008080; line-height: 1.5 !important;">21</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">22</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出结果为：</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">23</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">10</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">24</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">20</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">25</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">30</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">26</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">15</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">27</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">25</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">28</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">35</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 从上面的应用示例来看，相比于while方式，泛型for的方式提供了更清晰的实现逻辑。因为Lua在其内部替我们保存了迭代器函数，并在每次迭代时调用该隐式的内部迭代器，直到迭代器返回nil时结束循环。<br /><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp; &nbsp;2. 泛型for的语义：</span><br />&nbsp;&nbsp; &nbsp;上面示例中的迭代器有一个明显的缺点，即每次循环时都需要创建一个新的closure变量，否则第一次迭代成功后，再将该closure用于新的for循环时将会直接退出。<br />&nbsp;&nbsp; &nbsp;这里我们还是先详细的讲解一下Lua中泛型(for)的机制，之后再给出一个无状态迭代器的例子，以便于我们的理解。如果我们的迭代器实现为无状态迭代器，那么就不必为每一次的泛型(for)都重新声明一个新的迭代器变量了。<br />&nbsp;&nbsp; &nbsp;泛型(for)的语法如下：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;for &lt;var-list&gt; in &lt;exp-list&gt; do</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&lt;body&gt;</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;end</span><br />&nbsp;&nbsp; &nbsp;为了便于理解，由于我们在实际应用中<span style="color: #0000ff;">&lt;exp-list&gt;</span>通常只是包含一个表达式(expr)，因此简单起见，这里的说明将只是包含一个表达式，而不是表达式列表。现在我们先给出表达式的原型和实例，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> ipairs2(a)<br /><span style="color: #008080; line-height: 1.5 !important;">2</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> iter,a,<span style="color: #800080; line-height: 1.5 !important;">0</span><br /><span style="color: #008080; line-height: 1.5 !important;">3</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 该函数返回3个值，第一个为实际的迭代器函数变量，第二个是一个恒定对象，这里我们可以理解为待遍历的容器，第三个变量是在调用iter()函数时为其传入的初始值。<br />&nbsp;&nbsp; &nbsp;下面我们再看一下iter()函数的实现，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> iter(a, i)<br /><span style="color: #008080; line-height: 1.5 !important;">2</span>     i = i + <span style="color: #800080; line-height: 1.5 !important;">1</span><br /><span style="color: #008080; line-height: 1.5 !important;">3</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> v = a[i]<br /><span style="color: #008080; line-height: 1.5 !important;">4</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span> v <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;">5</span>         <span style="color: #0000ff; line-height: 1.5 !important;">return</span> i, v<br /><span style="color: #008080; line-height: 1.5 !important;">6</span>     <span style="color: #0000ff; line-height: 1.5 !important;">else</span><br /><span style="color: #008080; line-height: 1.5 !important;">7</span>         <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #0000ff; line-height: 1.5 !important;">nil</span>, <span style="color: #0000ff; line-height: 1.5 !important;">nil</span><br /><span style="color: #008080; line-height: 1.5 !important;">8</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">9</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 在迭代器函数iter()中返回了两个值，分别对应于table的key和value，其中key(返回的i)如果为nil，泛型(for)将会认为本次迭代已经结束。下面我们先看一下实际用例，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> ipairs2(a)<br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> iter,a,<span style="color: #800080; line-height: 1.5 !important;">0</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span> <br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span> <br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> iter(a, i)<br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span>     i = i + <span style="color: #800080; line-height: 1.5 !important;">1</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> v = a[i]<br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span> v <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;">10</span>         <span style="color: #0000ff; line-height: 1.5 !important;">return</span> i, v<br /><span style="color: #008080; line-height: 1.5 !important;">11</span>     <span style="color: #0000ff; line-height: 1.5 !important;">else</span><br /><span style="color: #008080; line-height: 1.5 !important;">12</span>         <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #0000ff; line-height: 1.5 !important;">nil</span>, <span style="color: #0000ff; line-height: 1.5 !important;">nil</span><br /><span style="color: #008080; line-height: 1.5 !important;">13</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">14</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">15</span> <br /><span style="color: #008080; line-height: 1.5 !important;">16</span> a = {<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">one</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">two</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">three</span><span style="color: #800000; line-height: 1.5 !important;">"</span>}<br /><span style="color: #008080; line-height: 1.5 !important;">17</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> k,v <span style="color: #0000ff; line-height: 1.5 !important;">in</span> ipairs2(a) <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">18</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(k, v)<br /><span style="color: #008080; line-height: 1.5 !important;">19</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">20</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出结果为：</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">21</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">1       one</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">22</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">2       two</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">23</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">3       three    </span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 这个例子中的泛型(for)写法可以展开为下面的基于while循环的方式，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> iter(a, i)<br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span>     i = i + <span style="color: #800080; line-height: 1.5 !important;">1</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> v = a[i]<br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span> v <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span>         <span style="color: #0000ff; line-height: 1.5 !important;">return</span> i, v<br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span>     <span style="color: #0000ff; line-height: 1.5 !important;">else</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span>         <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #0000ff; line-height: 1.5 !important;">nil</span>, <span style="color: #0000ff; line-height: 1.5 !important;">nil</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">10</span> <br /><span style="color: #008080; line-height: 1.5 !important;">11</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> ipairs2(a)<br /><span style="color: #008080; line-height: 1.5 !important;">12</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> iter,a,<span style="color: #800080; line-height: 1.5 !important;">0</span><br /><span style="color: #008080; line-height: 1.5 !important;">13</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">14</span> <br /><span style="color: #008080; line-height: 1.5 !important;">15</span> a = {<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">one</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">two</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">three</span><span style="color: #800000; line-height: 1.5 !important;">"</span>}<br /><span style="color: #008080; line-height: 1.5 !important;">16</span> <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">17</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> <span style="color: #008080; line-height: 1.5 !important;">_it</span>,<span style="color: #008080; line-height: 1.5 !important;">_s</span>,<span style="color: #008080; line-height: 1.5 !important;">_var</span> = ipairs2(a)<br /><span style="color: #008080; line-height: 1.5 !important;">18</span>     <span style="color: #0000ff; line-height: 1.5 !important;">while</span> <span style="color: #0000ff; line-height: 1.5 !important;">true</span> <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">19</span>         <span style="color: #0000ff; line-height: 1.5 !important;">local</span> var_1,var_2 = <span style="color: #008080; line-height: 1.5 !important;">_it</span>(<span style="color: #008080; line-height: 1.5 !important;">_s</span>,<span style="color: #008080; line-height: 1.5 !important;">_var</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">20</span>         <span style="color: #008080; line-height: 1.5 !important;">_var</span> = var_1<br /><span style="color: #008080; line-height: 1.5 !important;">21</span>         <span style="color: #0000ff; line-height: 1.5 !important;">if</span> <span style="color: #008080; line-height: 1.5 !important;">_var</span> == <span style="color: #0000ff; line-height: 1.5 !important;">nil</span> <span style="color: #0000ff; line-height: 1.5 !important;">then</span>  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">注意，这里只判断迭代器函数返回的第一个是否为nil。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">22</span>             <span style="color: #0000ff; line-height: 1.5 !important;">break</span><br /><span style="color: #008080; line-height: 1.5 !important;">23</span>         <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">24</span>         <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(var_1,var_2)<br /><span style="color: #008080; line-height: 1.5 !important;">25</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">26</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">27</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出结果同上。</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #800080; font-size: 15px;">3. 无状态迭代器的例子：</span><br />&nbsp;&nbsp;&nbsp; 这里的示例将实现遍历链表的迭代器。</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> getnext(list, node)  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">迭代器函数。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 2</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span> <span style="color: #0000ff; line-height: 1.5 !important;">not</span> node <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span>         <span style="color: #0000ff; line-height: 1.5 !important;">return</span> list<br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span>     <span style="color: #0000ff; line-height: 1.5 !important;">else</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span>         <span style="color: #0000ff; line-height: 1.5 !important;">return</span> node.<span style="color: #ff00ff; line-height: 1.5 !important;">next</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span> <br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> traverse(list)  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">泛型(for)的expression</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">10</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> getnext,list,<span style="color: #0000ff; line-height: 1.5 !important;">nil</span><br /><span style="color: #008080; line-height: 1.5 !important;">11</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">12</span> <br /><span style="color: #008080; line-height: 1.5 !important;">13</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">初始化链表中的数据。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">14</span> list = <span style="color: #0000ff; line-height: 1.5 !important;">nil</span><br /><span style="color: #008080; line-height: 1.5 !important;">15</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> line <span style="color: #0000ff; line-height: 1.5 !important;">in</span> <span style="color: #ff00ff; line-height: 1.5 !important;">io.lines</span>() <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">16</span>     line = { val = line, <span style="color: #ff00ff; line-height: 1.5 !important;">next</span> = list}<br /><span style="color: #008080; line-height: 1.5 !important;">17</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">18</span> <br /><span style="color: #008080; line-height: 1.5 !important;">19</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">以泛型(for)的形式遍历链表。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">20</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> node <span style="color: #0000ff; line-height: 1.5 !important;">in</span> traverse(list) <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">21</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(node.val)<br /><span style="color: #008080; line-height: 1.5 !important;">22</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 这里使用的技巧是将链表的头结点作为恒定状态(traverse返回的第二个值)，而将当前节点作为控制变量。第一次调用迭代器函数getnext()时，node为nil，因此函数返回list作为第一个结点。在后续调用中node不再为nil了，所以迭代器返回node.next，直到返回链表尾部的nil结点，此时泛型(for)将判断出迭代器的遍历已经结束。<br />&nbsp;&nbsp; &nbsp;最后需要说明的是，traverse()函数和list变量可以反复的调用而无需再创建新的closure变量了。这主要是因为迭代器函数(getnext)实现为无状态迭代器。<br /><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 4. 具有复杂状态的迭代器：</span><br />&nbsp;&nbsp; &nbsp;在上面介绍的迭代器实现中，迭代器需要保存许多状态，可是泛型(for)却只提供了恒定状态和控制变量用于状态的保存。一个最简单的办法是使用closure。当然我们还以将所有的信息封装到一个table中，并作为恒定状态对象传递给迭代器。虽说恒定状态变量本身是恒定的，即在迭代过程中不会换成其它对象，但是该对象所包含的数据是否变化则完全取决于迭代器的实现。就目前而言，由于table类型的恒定对象已经包含了所有迭代器依赖的信息，那么迭代器就完全可以忽略泛型(for)提供的第二个参数。下面我们就给出一个这样的实例，见如下代码：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> iterator<br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> allwords()<br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> state { line = <span style="color: #ff00ff; line-height: 1.5 !important;">io.read</span>(), pos = <span style="color: #800080; line-height: 1.5 !important;">1</span> }<br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> iterator, state<br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">iterator函数将是真正的迭代器</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 7</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> iterator(state)<br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span>     <span style="color: #0000ff; line-height: 1.5 !important;">while</span> state.line <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span>         <span style="color: #0000ff; line-height: 1.5 !important;">local</span> s,e = <span style="color: #ff00ff; line-height: 1.5 !important;">string.find</span>(state.line,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">%w+</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,state.pos)<br /><span style="color: #008080; line-height: 1.5 !important;">10</span>         <span style="color: #0000ff; line-height: 1.5 !important;">if</span> s <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;">11</span>             state.pos = e + <span style="color: #800080; line-height: 1.5 !important;">1</span><br /><span style="color: #008080; line-height: 1.5 !important;">12</span>             <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #ff00ff; line-height: 1.5 !important;">string.sub</span>(state.line,s,e)<br /><span style="color: #008080; line-height: 1.5 !important;">13</span>         <span style="color: #0000ff; line-height: 1.5 !important;">else</span><br /><span style="color: #008080; line-height: 1.5 !important;">14</span>             state.line = <span style="color: #ff00ff; line-height: 1.5 !important;">io.read</span>()<br /><span style="color: #008080; line-height: 1.5 !important;">15</span>             state.pos = <span style="color: #800080; line-height: 1.5 !important;">1</span><br /><span style="color: #008080; line-height: 1.5 !important;">16</span>         <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">17</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">18</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #0000ff; line-height: 1.5 !important;">nil</span><br /><span style="color: #008080; line-height: 1.5 !important;">19</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><img src ="http://www.cppblog.com/mmdengwo/aggbug/205792.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mmdengwo/" target="_blank">沛沛</a> 2014-02-17 17:36 <a href="http://www.cppblog.com/mmdengwo/archive/2014/02/17/205792.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Step By Step(Lua函数)</title><link>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205791.html</link><dc:creator>沛沛</dc:creator><author>沛沛</author><pubDate>Mon, 17 Feb 2014 09:36:00 GMT</pubDate><guid>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205791.html</guid><wfw:comment>http://www.cppblog.com/mmdengwo/comments/205791.html</wfw:comment><comments>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205791.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mmdengwo/comments/commentRss/205791.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mmdengwo/services/trackbacks/205791.html</trackback:ping><description><![CDATA[<p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><span style="font-size: 14pt;"><strong><span style="color: #ff0000;">一、函数：</span></strong></span><br /><br />&nbsp;&nbsp; &nbsp;在Lua中函数的调用方式和C语言基本相同，如：print("Hello World")和a = add(x, y)。唯一的差别是，如果函数只有一个参数，并且该参数的类型为字符串常量或table的构造器，那么圆括号可以省略，如print "Hello World"和f {x = 20, y = 20}。<br />&nbsp;&nbsp; &nbsp;Lua为面对对象式的调用也提供了一种特殊的语法--冒号操作符。表达式o.foo(o,x)的另一种写法是o:foo(x)。冒号操作符使调用o.foo时将o隐含的作为函数的第一个参数。<br />&nbsp;&nbsp; &nbsp;Lua中函数的声明方式如下：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;function add(a)</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;local sum = 0</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;for i, v in ipairs(a) do</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;sum = sum + v</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;end</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;return sum</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;end</span><br />&nbsp;&nbsp; &nbsp;在以上声明中，包含了函数名(add)，参数列表(a)，以及函数体。需要说明的是，Lua中实参和形参的数量可以不一致，一旦出现这种情况，Lua的处理规则等同于多重赋值，即实参多于形参，多出的部分被忽略，如果相反，没有被初始化的形参的缺省值为nil。<br /><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp; &nbsp;1. 多重返回值：</span><br />&nbsp;&nbsp; &nbsp;Lua支持返回多个结果值。如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> s,e = <span style="color: #ff00ff; line-height: 1.5 !important;">string.find</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">Hello Lua users</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">Lua</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">2</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">The begin index is </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. s .. <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">, the end index is </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. e .. <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">.</span><span style="color: #800000; line-height: 1.5 !important;">"</span>);<br /><span style="color: #008080; line-height: 1.5 !important;">3</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;"> The begin index is 7, the end index is 9.</span></pre></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 以上的代码示例只是演示了如何获取Lua函数的多个返回值，下面的示例将给出如何声明返回多个值的Lua函数。如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> maximum(a)<br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> mi = <span style="color: #800080; line-height: 1.5 !important;">1</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> m = a[mi]<br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span>     <span style="color: #0000ff; line-height: 1.5 !important;">for</span> i, val <span style="color: #0000ff; line-height: 1.5 !important;">in</span> <span style="color: #ff00ff; line-height: 1.5 !important;">ipairs</span>(a) <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span>         <span style="color: #0000ff; line-height: 1.5 !important;">if</span> val &gt; m <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span>             mi,m = i,val<br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span>         <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> m,mi<br /><span style="color: #008080; line-height: 1.5 !important;">10</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">11</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(maximum{<span style="color: #800080; line-height: 1.5 !important;">8</span>,<span style="color: #800080; line-height: 1.5 !important;">10</span>,<span style="color: #800080; line-height: 1.5 !important;">23</span>,<span style="color: #800080; line-height: 1.5 !important;">12</span>,<span style="color: #800080; line-height: 1.5 !important;">5</span>})<br /><span style="color: #008080; line-height: 1.5 !important;">12</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">23   3</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; Lua会调整一个函数的返回值数量以适应不同的调用情况。若将函数调用作为一条单独语句时，Lua会丢弃函数的所有返回值。若将函数作为表达式的一部分来调用时，Lua只保留函数的第一个返回值。只有当一个函数调用是一系列表达式中的最后一个元素时，才能获得所有返回值。这里先给出三个样例函数，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp;&nbsp; function foo0() end</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;function foo1() return "a" end</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;function foo2() return "a","b" end</span></p><table border="0" align="center" style="border-style: solid; border-color: silver; border-collapse: collapse; color: #000000; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px; line-height: 18px; width: 680px;"><tbody><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><strong><span style="color: #0000ff;">示例代码</span></strong></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><strong><span style="color: #0000ff;">结果</span></strong></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><strong><span style="color: #0000ff;">注释</span></strong></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">x,y = foo2()</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">x = "a", y = "b"</span></td><td rowspan="3" style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">函数调用时最后的(或仅有的)一个表达式，Lua会保留其尽可能多的返回值，用于匹配赋值变量。</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">x = foo2()</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">x = "a", 返回值"b"被忽略</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">x,y,z = 10,foo2()</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">x = 10, y = "a", z = "b"</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">x,y = foo0()</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">x = nil, y = nil</span></td><td rowspan="3" style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">如果一个函数没有返回值或者没有足够多的返回值，那么Lua会用nil来填补。</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">x,y = foo1()</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">x = "a", y = nil</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">x,y,z = foo2()</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">x = "a", y = "b", z = nil</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">x,y = foo2(),20</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">x = "a", y = 20</span></td><td rowspan="2" style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">如果一个函数调用不是一系列表达式的最后一个元素，那么将只产生一个值。</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">x,y = foo0(),20,30</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">x = nil, y = 20, 30被忽略。</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">print(foo0())</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;">&nbsp;</td><td rowspan="4" style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">当一个函数调用左右另一个函数调用的最后一个实参时，第一个函数的所有返回值都将作为实参传入第二个函数。</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">print(foo1())&nbsp;</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">a</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">print(foo2())</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">a&nbsp;&nbsp;&nbsp; b</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">print(foo2(),1)</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">a &nbsp;&nbsp; 1</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">t = {foo0()}&nbsp;</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">t = {} --空table&nbsp;</span></td><td rowspan="3" style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">table构造器可以完整的接收一个函数调用的所有结果，即不会有任何数量方面的调整。&nbsp;&nbsp;</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">t = {foo1()}&nbsp;</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">t = {"a"}&nbsp;</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">t = {foo2()}</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">t = {"a", "b"}</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">t = { foo0(), foo2(), 4}</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">t[1] = nil, t[2] = "a", t[3] = 4</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">如果函数调用不是作为最后一个元素，那么只返回函数的第一个结果值。</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">print((foo2()))</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">a</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">如果函数调用放入圆括号中，那么Lua将只返回该函数的第一个结果值。</span></td></tr></tbody></table><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 最后一个需要介绍的是Lua中unpack函数，该函数将接收数组作为参数，并从下标1开始返回该数组的所有元素。如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;/&gt; lua</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&gt; print(unpack{10,20,30})</span><br /><span style="color: #008000;">&nbsp;&nbsp; &nbsp;10&nbsp; 20&nbsp; 30</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&gt; a,b = unpack{10,20,30}</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&gt; print(a,b)</span><br /><span style="color: #008000;">&nbsp;&nbsp; &nbsp;10&nbsp; 20</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&gt; string.find(unpack{"hello","ll"})&nbsp;&nbsp;<span style="color: #008000;">--等同于string.find("hello","ll")</span></span><br />&nbsp;&nbsp;&nbsp; 在Lua中unpack函数是用C语言实现的。为了便于理解，下面给出在Lua中通过递归实现一样的效果，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> <span style="color: #ff00ff; line-height: 1.5 !important;">unpack</span>(t,i)<br /><span style="color: #008080; line-height: 1.5 !important;">2</span>     i = i <span style="color: #0000ff; line-height: 1.5 !important;">or</span> <span style="color: #800080; line-height: 1.5 !important;">1</span><br /><span style="color: #008080; line-height: 1.5 !important;">3</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span> t[i] <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;">4</span>         <span style="color: #0000ff; line-height: 1.5 !important;">return</span> t[i], <span style="color: #ff00ff; line-height: 1.5 !important;">unpack</span>(t,i + <span style="color: #800080; line-height: 1.5 !important;">1</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">5</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">6</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 2. 变长参数：</span><br />&nbsp;&nbsp; &nbsp;Lua中的函数可以接受不同数量的实参，其声明和使用方式如下：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> add(...)<br /><span style="color: #008080; line-height: 1.5 !important;">2</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> s = <span style="color: #800080; line-height: 1.5 !important;">0</span><br /><span style="color: #008080; line-height: 1.5 !important;">3</span>     <span style="color: #0000ff; line-height: 1.5 !important;">for</span> i, v <span style="color: #0000ff; line-height: 1.5 !important;">in</span> <span style="color: #ff00ff; line-height: 1.5 !important;">ipairs</span>{...} <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">4</span>         s = s + v<br /><span style="color: #008080; line-height: 1.5 !important;">5</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">6</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> s<br /><span style="color: #008080; line-height: 1.5 !important;">7</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">8</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(add(<span style="color: #800080; line-height: 1.5 !important;">3</span>,<span style="color: #800080; line-height: 1.5 !important;">4</span>,<span style="color: #800080; line-height: 1.5 !important;">5</span>,<span style="color: #800080; line-height: 1.5 !important;">6</span>,<span style="color: #800080; line-height: 1.5 !important;">7</span>))<br /><span style="color: #008080; line-height: 1.5 !important;">9</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出结果为：25</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 解释一下，函数声明中的(...)表示该函数可以接受不同数量的参数。当这个函数被调用时，所有的参数都被汇聚在一起，函数中访问它时，仍需用3个点(...)。但不同的是，此时这3个点将作为表达式来使用，如{...}表示一个由所有变参构成的数组。在含有变长参数的函数中个，同样可以带有固定参数，但是固定参数一定要在变长参数之前声明，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;function test(arg1,arg2,...)</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;...</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;end</span><br />&nbsp;&nbsp; &nbsp;关于Lua的变长参数最后需要说明的是，由于变长参数中可能包含nil值，因此再使用类似获取table元素数量(#)的方式获取变参的数量就会出现问题。如果要想始终获得正确的参数数量，可以使用Lua提供的select函数，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> i = <span style="color: #800080; line-height: 1.5 !important;">1</span>, <span style="color: #ff00ff; line-height: 1.5 !important;">select</span>(<span style="color: #800000; line-height: 1.5 !important;">'</span><span style="color: #800000; line-height: 1.5 !important;">#</span><span style="color: #800000; line-height: 1.5 !important;">'</span>,...) <span style="color: #0000ff; line-height: 1.5 !important;">do</span>  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">这里'#'值表示让select返回变参的数量(其中包括nil)。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">2</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> arg = <span style="color: #ff00ff; line-height: 1.5 !important;">select</span>(i, ...) <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">这里的i表示获取第i个变参，1为第一个。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">3</span>     <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">do something</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">4</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 3. 具名实参：</span><br />&nbsp;&nbsp; &nbsp;在函数调用时，Lua的传参规则和C语言相同，并不真正支持具名实参。但是我们可以通过table来模拟，比如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;function rename(old,new)</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;...</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;end</span><br />&nbsp;&nbsp; &nbsp;这里我们可以让上面的rename函数只接收一个参数，即table类型的参数，与此同时，该table对象将含有old和new两个key。如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;function rename(arg)</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;local old = arg.old</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;local new = arg.new</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;...</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;end</span><br />&nbsp;&nbsp; &nbsp;这种修改方式有些类似于JavaBean，即将多个参数合并为一个JavaBean。然而在使用时，Lua的table存在一个天然的优势，即如果函数只有一个参数且为string或table类型，在调用该函数时，可以不用加圆括号，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;rename {old = "oldfile.txt", new = "newfile.txt"}</span><br /><br /><span style="font-size: 14pt;"><strong><span style="color: #ff0000;">二、深入函数：</span></strong></span><br /><br />&nbsp;&nbsp; &nbsp;在Lua中函数和所有其它值一样都是匿名的，即它们都没有名称。在使用时都是操作持有该函数的变量，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;a = { p = print }</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;a.p("Hello World")</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;b = print</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;b("Hello World")</span><br />&nbsp;&nbsp; &nbsp;在声明Lua函数时，可以直接给出所谓的函数名，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;function foo(x) return 2 * x end</span><br />&nbsp;&nbsp; &nbsp;我们同样可以使用下面这种更为简化的方式声明Lua中的函数，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;foo = function(x) return 2 * x end</span><br />&nbsp;&nbsp; &nbsp;因此，我们可以将函数理解为由语句构成的类型值，同时将这个值赋值给一个变量。由此我们可以将表达式"function(x) &lt;body&gt; end"视为一种函数的构造式，就想table的{}一样。我们将这种函数构造式的结果称为一个"匿名函数"。下面的示例显示了匿名函数的方便性，它的使用方式有些类似于Java中的匿名类，如：<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000ff;">&nbsp;table.sort(test_table,function(a,b) return (a.name &gt; b.name) end)</span><br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #800080; font-size: 15px;">1. closure(闭合函数)：</span><br />&nbsp;&nbsp; &nbsp;若将一个函数写在另一个函数之内，那么这个位于内部的函数便可以访问外部函数中的局部变量，见如下示例：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> newCounter() <br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> i = <span style="color: #800080; line-height: 1.5 !important;">0</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span>() <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">匿名函数</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 4</span>         i = i + <span style="color: #800080; line-height: 1.5 !important;">1</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span>         <span style="color: #0000ff; line-height: 1.5 !important;">return</span> i<br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span> c1 = newCounter()<br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">The return value of first call is </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. c1())<br /><span style="color: #008080; line-height: 1.5 !important;">10</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">The return value of second call is </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. c1())<br /><span style="color: #008080; line-height: 1.5 !important;">11</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出结果为：</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">12</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">The return value of first call is 1</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">13</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">The return value of second call is 2</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 在上面的示例中，我们将newCounter()函数称为闭包函数。其函数体内的局部变量i被称为"非局部变量"，和普通局部变量不同的是该变量被newCounter函数体内的匿名函数访问并操作。再有就是在函数newCounter返回后，其值仍然被保留并可用于下一次计算。再看一下下面的调用方式。</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> newCounter() <br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> i = <span style="color: #800080; line-height: 1.5 !important;">0</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span>() <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">匿名函数</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 4</span>         i = i + <span style="color: #800080; line-height: 1.5 !important;">1</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span>         <span style="color: #0000ff; line-height: 1.5 !important;">return</span> i<br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span> c1 = newCounter()<br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span> c2 = newCounter()<br /><span style="color: #008080; line-height: 1.5 !important;">10</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">The return value of first call with c1 is </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. c1())<br /><span style="color: #008080; line-height: 1.5 !important;">11</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">The return value of first call with c2 is </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. c2())<br /><span style="color: #008080; line-height: 1.5 !important;">12</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">The return value of second call with c1 is </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. c1())<br /><span style="color: #008080; line-height: 1.5 !important;">13</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出结果为：</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">14</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">The return value of first call with c1 is 1</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">15</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">The return value of first call with c2 is 1</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">16</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">The return value of second call with c1 is 2</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 由此可以推出，Lua每次在给新的闭包变量赋值时，都会让不同的闭包变量拥有独立的"非局部变量"。下面的示例将给出基于闭包的更为通用性的用法：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span>     <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">这里将原有的文件打开函数赋值给"私有变量"oldOpen，该变量在块外无法访问。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 3</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> oldOpen = <span style="color: #ff00ff; line-height: 1.5 !important;">io.open</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span>     <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">新增一个匿名函数，用于判断本次文件打开操作的合法性。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 5</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> access_OK = <span style="color: #0000ff; line-height: 1.5 !important;">function</span>(filename,mode) &lt;检查访问权限&gt; <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span>     <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">将原有的io.open函数变量指向新的函数，同时在新函数中调用老函数以完成真正的打开操作。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 7</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">io.open</span> = <span style="color: #0000ff; line-height: 1.5 !important;">function</span>(filename,mode)<br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span>         <span style="color: #0000ff; line-height: 1.5 !important;">if</span> access_OK(filename,mode) <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span>             <span style="color: #0000ff; line-height: 1.5 !important;">return</span> oldOpen(filename,mode)<br /><span style="color: #008080; line-height: 1.5 !important;">10</span>         <span style="color: #0000ff; line-height: 1.5 !important;">else</span><br /><span style="color: #008080; line-height: 1.5 !important;">11</span>             <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #0000ff; line-height: 1.5 !important;">nil</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">Access denied</span><span style="color: #800000; line-height: 1.5 !important;">"</span><br /><span style="color: #008080; line-height: 1.5 !important;">12</span>         <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">13</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">14</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 上面的这个例子有些类似于设计模式中装饰者模式。<br /><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 2. 非全局函数：</span><br />&nbsp;&nbsp; &nbsp;从上一小节中可以看出，Lua中的函数不仅可以直接赋值给全局变量，同时也可以赋值给其他类型的变量，如局部变量和table中的字段等。事实上，Lua库中大多数table都带有函数，如io.read、math.sin等。这种写法有些类似于C++中的结构体。如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;Lib = {}</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;Lib.add = function(x,y) return x + y end</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;Lib.sub = function(x,y) return x - y end</span><br />&nbsp;&nbsp; &nbsp;或者是在table的构造式中直接初始化，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;Lib = { add = function(x,y) return x + y end,&nbsp;</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sub = function(x,y) return x - y end</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; }</span><br />&nbsp;&nbsp; &nbsp;除此之外，Lua还提供另外一种语法来定义此类函数，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;Lib = {}</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;function Lib.add(x,y) return x + y end</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;function Lib.sub(x,y) return x - y end</span><br />&nbsp;&nbsp; &nbsp;对于Lua中的局部函数，其语义在理解上也是非常简单的。由于Lua中都是以程序块作为执行单元，因此程序块内的局部函数在程序块外是无法访问的，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">2</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> f = <span style="color: #0000ff; line-height: 1.5 !important;">function</span>(x,y) <span style="color: #0000ff; line-height: 1.5 !important;">return</span> x + y <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">3</span>     <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">do something with f.</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">4</span>     f(<span style="color: #800080; line-height: 1.5 !important;">4</span>,<span style="color: #800080; line-height: 1.5 !important;">5</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">5</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span>  </pre></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 对于这种局部函数，Lua还提供另外一种更为简洁的定义方式，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;local function f(x,y) return x + y end</span><br />&nbsp;&nbsp; &nbsp;该写法等价于：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;local f</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;f = function(x,y) return x + y end</span><br /><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 3. 正确的尾调用：</span><br />&nbsp;&nbsp; &nbsp;在Lua中支持这样一种函数调用的优化，即&#8220;尾调用消除&#8221;。我们可以将这种函数调用方式视为goto语句，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;function f(x) return g(x) end</span><br />&nbsp;&nbsp; &nbsp;由于g(x)函数是f(x)函数的最后一条语句，在函数g返回之后，f()函数将没有任何指令需要被执行，因此在函数g()返回时，可以直接返回到f()函数的调用点。由此可见，Lua解释器一旦发现g()函数是f()函数的尾调用，那么在调用g()时将不会产生因函数调用而引起的栈开销。这里需要强调的是，尾调用函数一定是其调用函数的最后一条语句，否则Lua不会进行优化。然而事实上，我们在很多看似是尾调用的场景中，实际上并不是真正的尾调用，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;function f(x) g(x) end&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000;">--没有return语句的明确提示</span></span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;function f(x) return g(x) + 1&nbsp;<span style="color: #008000;">&nbsp;--在g()函数返回之后仍需执行一次加一的指令。</span></span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;function f(x) return x or g(x)&nbsp;<span style="color: #008000;">--如果g()函数返回多个值，该操作会强制要求g()函数只返回一个值。</span></span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;function f(x) return (g(x))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000;">--原因同上。</span></span><br />&nbsp;&nbsp; &nbsp;在Lua中，只有<strong><span style="color: #0000ff;">"return &lt;func&gt;(&lt;args&gt;)"</span></strong>形式才是标准的尾调用，至于参数中(args)是否包含表达式，由于表达式的执行是在函数调用之前完成的，因此不会影响该函数成为尾调用函数。</p><img src ="http://www.cppblog.com/mmdengwo/aggbug/205791.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mmdengwo/" target="_blank">沛沛</a> 2014-02-17 17:36 <a href="http://www.cppblog.com/mmdengwo/archive/2014/02/17/205791.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Step By Step(Lua表达式和语句)</title><link>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205790.html</link><dc:creator>沛沛</dc:creator><author>沛沛</author><pubDate>Mon, 17 Feb 2014 09:35:00 GMT</pubDate><guid>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205790.html</guid><wfw:comment>http://www.cppblog.com/mmdengwo/comments/205790.html</wfw:comment><comments>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205790.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mmdengwo/comments/commentRss/205790.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mmdengwo/services/trackbacks/205790.html</trackback:ping><description><![CDATA[<p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><span style="font-size: 14pt;"><strong><span style="color: #ff0000;">一、表达式：</span></strong></span><br /><br />&nbsp;&nbsp; &nbsp;<span style="color: #800080; font-size: 15px;">1. 算术操作符：</span><br />&nbsp;&nbsp; &nbsp;Lua支持常规算术操作符有：二元的&#8220;+&#8221;、&#8220;-&#8221;、&#8220;*&#8221;、&#8220;/&#8221;、&#8220;^&#8221;(指数)、&#8220;%&#8221;(取模)，一元的&#8220;-&#8221;(负号)。所有这些操作符都可用于实数。然而需要特别说明的是取模操作符(<span style="color: #0000ff;"><strong>%</strong></span>)，Lua中对该操作符的定义为：<br />&nbsp;&nbsp; &nbsp;<span style="color: #0000ff;">a % b == a - floor(a / b) * b</span><br />&nbsp;&nbsp; &nbsp;由此可以推演出x % 1的结果为x的小数部分，而x - x % 1的结果则为x的整数部分。类似的，x - x % 0.01则是x精确到小数点后两位的结果。<br />&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp; &nbsp;<span style="font-size: 15px; color: #800080;">2. 关系操作符：</span><br />&nbsp;&nbsp; &nbsp;Lua支持的关系操作符有：&gt;、&lt;、&gt;=、&lt;=、==、~=，所有这些操作符的结果均为true或false。<br />&nbsp;&nbsp; &nbsp;操作符==用于相等性测试，操作符~=用于不等性测试。这两个操作符可以应用于任意两个值。如果两个值的类型不同，Lua就认为他们不等。nil值与其自身相等。对于table、userdata和函数，Lua是通过引用进行比较的。也就是说，只有当他们引用同一个对象时，才视为相等。如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> a = {}<br /><span style="color: #008080; line-height: 1.5 !important;">2</span> a.x = <span style="color: #800080; line-height: 1.5 !important;">1</span><br /><span style="color: #008080; line-height: 1.5 !important;">3</span> a.y = <span style="color: #800080; line-height: 1.5 !important;">0</span><br /><span style="color: #008080; line-height: 1.5 !important;">4</span> b = {}<br /><span style="color: #008080; line-height: 1.5 !important;">5</span> b.x = <span style="color: #800080; line-height: 1.5 !important;">1</span><br /><span style="color: #008080; line-height: 1.5 !important;">6</span> b.y = <span style="color: #800080; line-height: 1.5 !important;">1</span><br /><span style="color: #008080; line-height: 1.5 !important;">7</span> c = a</pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 其结果是a == c，但a ~= b。<br />&nbsp;&nbsp; &nbsp;对于字符串的比较，Lua是按照字符次序比较的。<br />&nbsp;&nbsp;&nbsp;&nbsp;<br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp; &nbsp;3. 逻辑操作符：</span><br />&nbsp;&nbsp; &nbsp;Lua支持的逻辑操作符有：and、or和not。与条件控制语句一样，所有的逻辑操作符都将false和nil视为假，其他的结果均为真。和其他大多数语言一样，Lua中的and和or都使用&#8220;短路原则&#8221;。在Lua中有一种惯用写法"<span style="color: #0000ff;">x = x or v</span>"，它等价于：<span style="color: #0000ff;">if not x then x = v end</span>。这里还有一种基于&#8220;短路原则&#8221;的惯用写法，如：<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000ff;">&nbsp;max = (x &gt; y) and x or y</span><br />&nbsp;&nbsp; &nbsp;这等价于C语言中<span style="color: #0000ff;">max = (x &gt; y) ? x : y</span>。由于x和y均为数值，因此它们的结果将始终为true。<br />&nbsp;&nbsp; &nbsp;<br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp; &nbsp;4. 字符串连接：</span><br />&nbsp;&nbsp; &nbsp;前一篇Blog已经提到了字符串连接操作符(..)，这里再给出一些简单的示例。<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;/&gt; lua</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&gt; print("Hello " .. "World)</span><br /><span style="color: #008000;">&nbsp;&nbsp; &nbsp;Hello World</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&gt; print(0 .. 1)&nbsp;<span style="color: #008000;">&nbsp;--即使连接操作符的操作数为数值类型，在执行时Lua仍会将其自动转换为字符串。</span></span><br />&nbsp;&nbsp; &nbsp;<span style="color: #008000;">01</span><br /><br />&nbsp;&nbsp;&nbsp;<span style="color: #800080; font-size: 15px;">&nbsp;5. table构造器：</span><br />&nbsp;&nbsp; &nbsp;构造器用于构建和初始化table的表达式。这是Lua特有的表达式，也是Lua中最有用、最通用的机制之一。其中最简单的构造器是空构造器{}，用于创建空table。我们通过构造器还可以初始化数组，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> days = {<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">Sunday</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">Monday</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">Tuesday</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">Wednesday</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">Thursday</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">Friday</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">Saturday</span><span style="color: #800000; line-height: 1.5 !important;">"</span>}<br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> i = <span style="color: #800080; line-height: 1.5 !important;">1</span>,#days <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(days[i])<br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出结果为</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 6</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">Sunday</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 7</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">Monday</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 8</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">Tuesday</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 9</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">Wednesday</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">10</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">Thursday</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">11</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">Friday</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">12</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">Saturday</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 从输出结果可以看出，days在构造后会将自动初始化，其中days[1]被初始化为"Sunday"，days[2]为"Monday"，以此类推。<br />&nbsp;&nbsp;&nbsp; Lua中还提供了另外一种特殊的语法用于初始化记录风格的table。如：<span style="color: #0000ff;">a = { x = 10, y = 20 }</span>，其等价于：<span style="color: #0000ff;">a = {}; a.x = 10; a.y = 20</span><br />&nbsp;&nbsp; &nbsp;在实际编程时我们也可以将这两种初始化方式组合在一起使用，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;">polyline = {color = <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">blue</span><span style="color: #800000; line-height: 1.5 !important;">"</span>, thickness = <span style="color: #800080; line-height: 1.5 !important;">2</span>, npoints = <span style="color: #800080; line-height: 1.5 !important;">4</span>, <br />    {x = <span style="color: #800080; line-height: 1.5 !important;">0</span>, y = <span style="color: #800080; line-height: 1.5 !important;">0</span>},<br />    {x = <span style="color: #800080; line-height: 1.5 !important;">10</span>, y = <span style="color: #800080; line-height: 1.5 !important;">0</span>},<br />    {x = -<span style="color: #800080; line-height: 1.5 !important;">10</span>, y = <span style="color: #800080; line-height: 1.5 !important;">1</span>},<br />    {x = <span style="color: #800080; line-height: 1.5 !important;">0</span>, y = <span style="color: #800080; line-height: 1.5 !important;">1</span>} }<br /><span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(polyline[<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">color</span><span style="color: #800000; line-height: 1.5 !important;">"</span>]);<br /><span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(polyline[<span style="color: #800080; line-height: 1.5 !important;">2</span>].x)<br /><span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(polyline[<span style="color: #800080; line-height: 1.5 !important;">4</span>].y)<br /><span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出结果如下：</span><span style="color: #008000; line-height: 1.5 !important;"><br />--</span><span style="color: #008000; line-height: 1.5 !important;">blue</span><span style="color: #008000; line-height: 1.5 !important;"><br />--</span><span style="color: #008000; line-height: 1.5 !important;">10</span><span style="color: #008000; line-height: 1.5 !important;"><br />--</span><span style="color: #008000; line-height: 1.5 !important;">1</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 除了以上两种构造初始化方式之外，Lua还提供另外一种更为通用的方式，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> opnames = { [<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">+</span><span style="color: #800000; line-height: 1.5 !important;">"</span>] = <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">add</span><span style="color: #800000; line-height: 1.5 !important;">"</span>, [<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">-</span><span style="color: #800000; line-height: 1.5 !important;">"</span>] = <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">sub</span><span style="color: #800000; line-height: 1.5 !important;">"</span>, [<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">*</span><span style="color: #800000; line-height: 1.5 !important;">"</span>] = <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">mul</span><span style="color: #800000; line-height: 1.5 !important;">"</span>, [<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">/</span><span style="color: #800000; line-height: 1.5 !important;">"</span>] = <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">div</span><span style="color: #800000; line-height: 1.5 !important;">"</span>}<br /><span style="color: #008080; line-height: 1.5 !important;">2</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(opnames[<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">+</span><span style="color: #800000; line-height: 1.5 !important;">"</span>])<br /><span style="color: #008080; line-height: 1.5 !important;">3</span> i = <span style="color: #800080; line-height: 1.5 !important;">20</span>; s = <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">-</span><span style="color: #800000; line-height: 1.5 !important;">"</span><br /><span style="color: #008080; line-height: 1.5 !important;">4</span> a = { [i + <span style="color: #800080; line-height: 1.5 !important;">0</span>] = s, [i + <span style="color: #800080; line-height: 1.5 !important;">1</span>] = s .. s, [i + <span style="color: #800080; line-height: 1.5 !important;">2</span>] = s..s..s }<br /><span style="color: #008080; line-height: 1.5 !important;">5</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(a[<span style="color: #800080; line-height: 1.5 !important;">22</span>])</pre></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 对于table的构造器，还有两个需要了解的语法规则，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp;&nbsp; a = { [1] = "red", [2] = "green", [3] = "blue", } &nbsp;</span><br />&nbsp;&nbsp;&nbsp; 这里需要注意最后一个元素的后面仍然可以保留逗号(,)，这一点类似于C语言中的枚举。<br />&nbsp;&nbsp; &nbsp;<span style="color: #0000ff;">a = {x = 10, y = 45; "one", "two", "three" }</span><br />&nbsp;&nbsp;&nbsp; 可以看到上面的声明中同时存在逗号(,)和分号(;)两种元素分隔符，这种写法在Lua中是允许的。我们通常会将分号(;)用于分隔不同初始化类型的元素，如上例中分号之前的初始化方式为记录初始化方式，而后面则是数组初始化方式。<br /><br /><span style="font-size: 14pt;"><strong><span style="color: #ff0000;">二、语句：</span></strong></span><br /><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp; &nbsp;1. 赋值语句：</span><br />&nbsp;&nbsp; &nbsp;Lua中的赋值语句和其它编程语言基本相同，唯一的差别是Lua支持&#8220;多重赋值&#8221;，如：a, b = 10, 2 * x，其等价于a = 10; b = 2 * x。然而需要说明的是，Lua在赋值之前需要先计算等号右边的表达式，在每一个表达式都得到结果之后再进行赋值。因此，我们可以这样写变量交互：<span style="color: #0000ff;">x,y = y,x</span>。如果等号右侧的表达式数量少于左侧变量的数量，Lua会将左侧多出的变量的值置为nil，如果相反，Lua将忽略右侧多出的表达式。<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #800080; font-size: 15px;">2. 局部变量与块：</span><br />&nbsp;&nbsp; &nbsp;Lua中的局部变量定义语法为：local i = 1，其中local关键字表示该变量为局部变量。和全局变量不同的是，局部变量的作用范围仅限于其所在的程序块。Lua中的程序可以为控制结构的执行体、函数执行体或者是一个程序块，如：<br />&nbsp;&nbsp; &nbsp;下面的x变量仅在while循环内有效。</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">while</span> i &lt;= x <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">2</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> x = i * <span style="color: #800080; line-height: 1.5 !important;">2</span><br /><span style="color: #008080; line-height: 1.5 !important;">3</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(x)<br /><span style="color: #008080; line-height: 1.5 !important;">4</span>     i = i + <span style="color: #800080; line-height: 1.5 !important;">1</span><br /><span style="color: #008080; line-height: 1.5 !important;">5</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 如果是在交互模式下，当执行local x = 0之后，该变量x所在的程序即以结束，后面的Lua语句将被视为新的程序块。如果想避免此类问题，我们可以显式的声明程序块，这样即便是在交互模式下，局部变量仍然能保持其块内有效性，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">2</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> a2 = <span style="color: #800080; line-height: 1.5 !important;">2</span> * a<br /><span style="color: #008080; line-height: 1.5 !important;">3</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> d = (b ^ <span style="color: #800080; line-height: 1.5 !important;">2</span> - <span style="color: #800080; line-height: 1.5 !important;">4</span> * a) ^ (<span style="color: #800080; line-height: 1.5 !important;">1</span> / <span style="color: #800080; line-height: 1.5 !important;">2</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">4</span>     x1 = (-b + d) / a2<br /><span style="color: #008080; line-height: 1.5 !important;">5</span>     x2 = (-b - d) / a2<br /><span style="color: #008080; line-height: 1.5 !important;">6</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span>  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">a2和d的作用域至此结束。</span></pre></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 和其它编程语言一样，如果有可能尽量使用局部变量，以免造成全局环境的变量名污染。同时由于局部变量的有效期更短，这样垃圾收集器可以及时对其进行清理，从而得到更多的可用内存。&nbsp;&nbsp; &nbsp;<br /><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 3. 控制结构：</span><br />&nbsp;&nbsp; &nbsp;Lua中提供的控制语句和其它大多数开发语言所提供的基本相同，因此这里仅仅是进行简单的列举。然后再给出差异部分的详细介绍。如：<br />&nbsp;&nbsp; &nbsp;1). if then else<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;if a &lt; 0 then&nbsp;</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; b = 0</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;else</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; b = 1</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;end</span><br />&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp; &nbsp;2). if elseif else then<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;if a &lt; 0 then&nbsp;</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; b = 0</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;elseif a == 0 then</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; b = 1</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;else</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; b = 2</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;end</span><br />&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp; &nbsp;3). while<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;local i= 1</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;while a[i] do</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;print(a[i])</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;i = i + 1</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;end</span><br />&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp; &nbsp;4). repeat<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;repeat</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; line = io.read()</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;until line ~= ""&nbsp;<span style="color: #008000;">--直到until的条件为真时结束。</span></span><br /><span style="color: #008000;">&nbsp;&nbsp; &nbsp;print(line)</span><br />&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp; &nbsp;5). for<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;for var = begin, end, step do<span style="color: #008000;">&nbsp;--如果没有step变量，begin的缺省步长为1。</span></span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;i = i + 1</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;end</span><br />&nbsp;&nbsp; &nbsp;需要说明的是，for循环开始处的三个变量begin、end和step，如果它们使表达式的返回值，那么该表达式将仅执行一次。再有就是不要在for的循环体内修改变量var的值，否则会导致不可预知的结果。<br />&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp; &nbsp;6). foreach<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;for i, v in ipairs(a) do&nbsp;&nbsp;<span style="color: #008000;">--ipairs是Lua自带的系统函数，返回遍历数组的迭代器。</span></span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;print(v)</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;end</span><br />&nbsp;&nbsp; &nbsp;<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;for k in pairs(t) do&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;<span style="color: #008000;">--打印table t中的所有key。</span></span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;print(k)</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;end</span><br />&nbsp;&nbsp;&nbsp; 见如下示例代码：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> days = {<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">Sunday</span><span style="color: #800000; line-height: 1.5 !important;">"</span>, <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">Monday</span><span style="color: #800000; line-height: 1.5 !important;">"</span>, <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">Tuesday</span><span style="color: #800000; line-height: 1.5 !important;">"</span>, <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">Wednesday</span><span style="color: #800000; line-height: 1.5 !important;">"</span>, <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">Thursday</span><span style="color: #800000; line-height: 1.5 !important;">"</span>, <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">Friday</span><span style="color: #800000; line-height: 1.5 !important;">"</span>, <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">Saturday</span><span style="color: #800000; line-height: 1.5 !important;">"</span> }<br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span> revDays = {}<br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> k, v <span style="color: #0000ff; line-height: 1.5 !important;">in</span> <span style="color: #ff00ff; line-height: 1.5 !important;">ipairs</span>(days) <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span>     revDays[v] = k<br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span> <br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> k <span style="color: #0000ff; line-height: 1.5 !important;">in</span> <span style="color: #ff00ff; line-height: 1.5 !important;">pairs</span>(revDays) <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(k .. <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;"> = </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. revDays[k])<br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">10</span> <br /><span style="color: #008080; line-height: 1.5 !important;">11</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出结果为：</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">12</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">Saturday = 7</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">13</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">Tuesday = 3</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">14</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">Wednesday = 4</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">15</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">Friday = 6</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">16</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">Sunday = 1</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">17</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">Thursday = 5</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">18</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">Monday = 2</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 7). break<br />&nbsp;&nbsp; &nbsp;和C语言中的break语义完全相同，即跳出最内层循环。</p><img src ="http://www.cppblog.com/mmdengwo/aggbug/205790.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mmdengwo/" target="_blank">沛沛</a> 2014-02-17 17:35 <a href="http://www.cppblog.com/mmdengwo/archive/2014/02/17/205790.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Step By Step(Lua基础知识)</title><link>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205789.html</link><dc:creator>沛沛</dc:creator><author>沛沛</author><pubDate>Mon, 17 Feb 2014 09:33:00 GMT</pubDate><guid>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205789.html</guid><wfw:comment>http://www.cppblog.com/mmdengwo/comments/205789.html</wfw:comment><comments>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205789.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mmdengwo/comments/commentRss/205789.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mmdengwo/services/trackbacks/205789.html</trackback:ping><description><![CDATA[<p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><span style="font-size: 14pt;"><strong><span style="color: #ff0000;">一、基础知识：</span></strong></span><br /><br />&nbsp;&nbsp; &nbsp;<span style="color: #800080; font-size: 15px;">1. 第一个程序和函数：</span><br />&nbsp;&nbsp; &nbsp;在目前这个学习阶段，运行Lua程序最好的方式就是通过Lua自带的解释器程序，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;/&gt; lua</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&gt; print("Hello World")</span><br />&nbsp;&nbsp; &nbsp;<span style="color: #008000;">Hello World</span><br />&nbsp;&nbsp; &nbsp;这样我们就可以以交互性的方式输入lua代码，并立即得到执行结果了。对于代码块较少的测试程序来说，这种方式确实是非常方便的，然而对于相对复杂的程序而言，这种方式就不是很合适了。如果是这样，我们可以将Lua代码保存到一个独立的Lua程序文件中，之后再通过Lua解释器程序以命令行参数的形式执行文件中的Lua代码。如我们将下面的Lua代码保存到test.lua的文件中：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> fact(n)<br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span> n == <span style="color: #800080; line-height: 1.5 !important;">0</span> <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span>         <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #800080; line-height: 1.5 !important;">1</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span>     <span style="color: #0000ff; line-height: 1.5 !important;">else</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span>         <span style="color: #0000ff; line-height: 1.5 !important;">return</span> n * fact(n - <span style="color: #800080; line-height: 1.5 !important;">1</span>)<br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">Enter a number:</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span> a = <span style="color: #ff00ff; line-height: 1.5 !important;">io.read</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">*number</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">10</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(fact(a))</pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><span style="color: #0000ff;">&nbsp;&nbsp;&nbsp; /&gt; lua D:/test.lua</span><br /><span style="color: #008000;">&nbsp;&nbsp; &nbsp;Enter a number:</span><br /><span style="color: #008000;">&nbsp;&nbsp; &nbsp;4</span><br /><span style="color: #008000;">&nbsp;&nbsp; &nbsp;24<br /><br /><span style="font-size: 15px; color: #800080;">&nbsp;&nbsp; &nbsp;2. 代码规范：</span><br /><span style="color: #000000;">&nbsp;&nbsp; &nbsp;1). Lua的多条语句之间并不要求任何分隔符，如C语言的分号(;)，其中换行符也同样不能起到语句分隔的作用。因此下面的写法均是合法的。如：</span><br /></span></p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> a = <span style="color: #800080; line-height: 1.5 !important;">1</span><br /><span style="color: #008080; line-height: 1.5 !important;">2</span> b = a * <span style="color: #800080; line-height: 1.5 !important;">2</span><br /><span style="color: #008080; line-height: 1.5 !important;">3</span>     <br /><span style="color: #008080; line-height: 1.5 !important;">4</span> a = <span style="color: #800080; line-height: 1.5 !important;">1</span>;<br /><span style="color: #008080; line-height: 1.5 !important;">5</span> b = a * <span style="color: #800080; line-height: 1.5 !important;">2</span>;<br /><span style="color: #008080; line-height: 1.5 !important;">6</span>     <br /><span style="color: #008080; line-height: 1.5 !important;">7</span> a = <span style="color: #800080; line-height: 1.5 !important;">1</span>; b = a * <span style="color: #800080; line-height: 1.5 !important;">2</span>;<br /><span style="color: #008080; line-height: 1.5 !important;">8</span> a = <span style="color: #800080; line-height: 1.5 !important;">1</span>  b = a * <span style="color: #800080; line-height: 1.5 !important;">2</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><span style="color: #008000;"><span style="color: #000000;">&nbsp;&nbsp;&nbsp; 2). 通过dofile()方法引用其他Lua文件中的函数，如：</span><br /></span></p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> fact(n)<br /><span style="color: #008080; line-height: 1.5 !important;">2</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span> n == <span style="color: #800080; line-height: 1.5 !important;">0</span> <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;">3</span>         <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #800080; line-height: 1.5 !important;">1</span><br /><span style="color: #008080; line-height: 1.5 !important;">4</span>     <span style="color: #0000ff; line-height: 1.5 !important;">else</span><br /><span style="color: #008080; line-height: 1.5 !important;">5</span>         <span style="color: #0000ff; line-height: 1.5 !important;">return</span> n * fact(n - <span style="color: #800080; line-height: 1.5 !important;">1</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">6</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">7</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><span style="color: #008000;"><span style="color: #000000;">&nbsp;&nbsp;&nbsp; 将上面的函数保存到test2.lua文件中。</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;/&gt; lua</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&gt; dofile("d:/test2.lua")</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&gt; print(fact(4))</span><br />&nbsp;&nbsp; &nbsp;24<br /><span style="color: #000000;">&nbsp;&nbsp; &nbsp;3). 词法规范。</span><br /><span style="color: #000000;">&nbsp;&nbsp; &nbsp;和大多数其它语言一样，在声明变量时，变量名可以由任意字母、数字和下划线构成，但是不能以数字开头。在Lua中还有一个特殊的规则，即以下划线(_)开头，后面紧随多个大写字母(<span style="color: #0000ff;">_VERSION</span>)，这些变量一般被Lua保留并用于特殊用途，因此我们在声明变量时需要尽量避免这样的声明方式，以免给后期的维护带来不必要的麻烦。</span><br /><span style="color: #000000;">&nbsp;&nbsp; &nbsp;Lua是大小写敏感的，因此对于一些Lua保留关键字的使用要特别小心，如and。但是And和AND则不是Lua的保留字。</span><br /><span style="color: #000000;">&nbsp;&nbsp; &nbsp;4). Lua中的注释分为两种，一种是单行注释，如：</span><br /></span><span style="color: #008000;">&nbsp;&nbsp; &nbsp;--This is a single line comment.</span><br /><span style="color: #008000;"><span style="color: #000000;">&nbsp;&nbsp; &nbsp;另外一种是多行注释，如：</span><br /></span><span style="color: #008000;">&nbsp;&nbsp; &nbsp;--[[</span><br /><span style="color: #008000;">&nbsp;&nbsp; &nbsp;This is a multi-lines comment.</span><br /><span style="color: #008000;">&nbsp;&nbsp; &nbsp;--]]</span><br /><br />&nbsp;&nbsp; &nbsp;<span style="color: #800080; font-size: 15px;">3. 全局变量：</span><br />&nbsp;&nbsp; &nbsp;在Lua中全局变量不需要声明，直接赋值即可。如果直接访问未初始化的全局变量，Lua也不会报错，直接返回nil。如果不想再使用该全局变量，可直接将其置为nil。如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;/&gt; lua</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&gt; print(b)</span><br /><span style="color: #008000;">&nbsp;&nbsp; &nbsp;nil</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&gt; b = 10</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&gt; print(b)</span><br /><span style="color: #008000;">&nbsp;&nbsp; &nbsp;10</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&gt; b = nil</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&gt; print(b)</span><br /><span style="color: #008000;">&nbsp;&nbsp; &nbsp;nil</span><br />&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp;&nbsp;<span style="font-size: 15px; color: #800080;">&nbsp;4. 解释器程序：</span><br />&nbsp;&nbsp; &nbsp;命令行用法如下：<br />&nbsp;&nbsp; &nbsp;<strong><span style="color: #0000ff;">lua [options] [lua-script [arguments] ]</span></strong><br />&nbsp;&nbsp; &nbsp;该工具的命令行选项主要有以下3个：<br />&nbsp;&nbsp; &nbsp;<strong><span style="color: #0000ff;">-e</span></strong>: 可以直接执行命令行中Lua代码，如：lua -e "print(\"Hello World\")"<br />&nbsp;&nbsp; &nbsp;<strong><span style="color: #0000ff;">-l</span></strong>: 加载该选项后的Lua库文件，如：lua -l mylib -e "x = 10"，该命令在执行之前先将mylib中的Lua代码加载到内存中，在后面的命令中就可以直接使用该文件中定义的Lua函数了。<br />&nbsp;&nbsp; &nbsp;<strong><span style="color: #0000ff;">-i</span></strong>: 在执行完指定的Lua程序文件之后，并不退出解释器程序，而是直接进入该程序的交互模式。&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp; &nbsp;在解释器程序的交互模式下，我们可以通过在表达式前加等号(=)标识符的方式直接输出表达式的执行结果。通过该方式，我们可以将该程序用于计算器，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;/&gt; lua</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&gt; = 3 + 1 + 4</span><br /><span style="color: #008000;">&nbsp;&nbsp; &nbsp;8</span><br />&nbsp;&nbsp; &nbsp;该小节最后需要介绍的是lua脚本的命令行参数访问规则。如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;/&gt; lua lua-script.lua a b c</span><br />&nbsp;&nbsp; &nbsp;在该脚本的程序入口，lua解释器会将所有命令行参数创建一个名为arg的table。其中脚本名(lua-script.lua)位于table索引的0位置上。它的第一个参数(a)则位于索引1，其它的参数以此类推。这种索引方式和C语言中读取命令行参数的规则相同。但是不同的是，Lua提供了负数索引，用以访问脚本名称之前的命令行参数，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;arg[-1] = lua</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;arg[0] = lua-script.lua</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;arg[1] = a</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;arg[2] = b</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;arg[3] = c</span><br /><br /><span style="font-size: 14pt;"><strong><span style="color: #ff0000;">二、类型与值：</span></strong></span><br /><br />&nbsp;&nbsp; &nbsp;Lua是一种动态类型的语言。其语言本身没有提供类型定义的语法，每个值都&#8220;携带&#8221;了它自身的类型信息。在Lua中有8中基础类型，分别是：nil、boolean、number、string、userdata、function、thread和table。我们可以通过type函数获得变量的类型信息，该类型信息将以字符串的形式返回。如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&gt; print(type("hello world"))</span><br /><span style="color: #008000;">&nbsp;&nbsp; &nbsp;string</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&gt; print(type(10.4))</span><br /><span style="color: #008000;">&nbsp;&nbsp; &nbsp;number</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&gt; print(type(print))</span><br /><span style="color: #008000;">&nbsp;&nbsp; &nbsp;function</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&gt; print(type(true))</span><br /><span style="color: #008000;">&nbsp;&nbsp; &nbsp;boolean</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&gt; print(type(nil))</span><br /><span style="color: #008000;">&nbsp;&nbsp; &nbsp;nil</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&gt; print(type(type(X)))</span><br /><span style="color: #008000;">&nbsp;&nbsp; &nbsp;string</span><br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #800080; font-size: 15px;">1. nil(空)：</span><br />&nbsp;&nbsp; &nbsp;nil是一种类型，它只有一个值nil，它的主要功能是由于区别其他任何值。就像之前所说的，一个全局变量在第一次赋值前的默认值的默认值就是nil，将nil赋予一个全局变量等同于删除它。Lua将nil用于表示一种&#8220;无效值&#8221;的情况。<br />&nbsp;&nbsp; &nbsp;<br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp; &nbsp;2. boolean(布尔)：</span><br />&nbsp;&nbsp; &nbsp;该类型有两个可选值：false和true。在Lua中只有当值是false和nil时才视为&#8220;假&#8221;，其它值均视为真，如数字零和空字符串，这一点和C语言是不同的。<br />&nbsp;&nbsp; &nbsp;<br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp; &nbsp;3. number(数字)：</span><br />&nbsp;&nbsp; &nbsp;Lua中的number用于表示实数。Lua中没有专门的类型表示整数。<br />&nbsp;&nbsp; &nbsp;<br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp; &nbsp;4. string(字符串)：</span><br />&nbsp;&nbsp; &nbsp;Lua中的字符串通常表示&#8220;一个字符序列&#8221;。字符串类型的变量是不可变的，因此不能像C语言中那样直接修改字符串的某一个字符，而是在修改的同时创建了新的字符串。如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> a = <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">one string</span><span style="color: #800000; line-height: 1.5 !important;">"</span><br /><span style="color: #008080; line-height: 1.5 !important;">2</span> b = <span style="color: #ff00ff; line-height: 1.5 !important;">string.gsub</span>(a,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">one</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">another</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">3</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(a)<br /><span style="color: #008080; line-height: 1.5 !important;">4</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(b)</pre></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><span style="color: #0000ff;">&nbsp;&nbsp;&nbsp; /&gt; lua d:/test.lua&nbsp;&nbsp; &nbsp;</span><br /><span style="color: #008000;">&nbsp;&nbsp; &nbsp;one string</span><br /><span style="color: #008000;">&nbsp;&nbsp; &nbsp;anotner string</span><br />&nbsp;&nbsp;&nbsp; Lua支持和C语言类似的字符转义序列，见下表：</p><table border="0" align="center" style="border-style: solid; border-color: silver; border-collapse: collapse; color: #000000; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px; line-height: 18px; width: 500px;"><tbody><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">转义符</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">描述</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">\a</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">响铃</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">\b</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">退格</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">\n</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">换行</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">\r</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">回车</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">\t</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">水平Tab</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">\\</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">反斜杠</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">\"</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">双引号</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">\'</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">单引号</span></td></tr></tbody></table><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 在Lua中还可以通过<span style="color: #0000ff;">[[ all strings ]]</span>的方式来禁用<strong><span style="color: #0000ff;">[[ ]]</span></strong>中转义字符，如：<br />&nbsp;&nbsp; &nbsp;<span style="color: #0000ff;">page = [[ &lt;html&gt; &lt;head&gt; &lt;title&gt; An Html Page &lt;/title&gt; &lt;/head&gt; ]]</span><br />&nbsp;&nbsp; &nbsp;如果两个方括号中包含这样的内容：a = b[c[i]]，这样将会导致Lua的误解析，因此在这种情况下，我们可以将其改为<strong><span style="color: #0000ff;">[===[</span></strong>&nbsp;和<strong><span style="color: #0000ff;">&nbsp;]===]</span></strong>的形式，从而避免了误解析的发生。<br />&nbsp;&nbsp; &nbsp;Lua提供了运行时的数字与字符串的自动转换。如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&gt; print("10" + 1)</span><br /><span style="color: #008000;">&nbsp;&nbsp; &nbsp;11</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&gt; print("10 + 1")</span><br /><span style="color: #008000;">&nbsp;&nbsp; &nbsp;10 + 1</span><br />&nbsp;&nbsp; &nbsp;如果在实际编程中，不希望两个数字字符串被自动转换，而是实现字符串之间的连接，可以通过<span style="color: #0000ff;"><strong>" .. "</strong></span>操作符来完成。如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;&gt; print(10 .. 20)</span><br /><span style="color: #008000;">&nbsp;&nbsp; &nbsp;1020</span><br />&nbsp;&nbsp; &nbsp;注意..和两边的数字之间必须留有空格，否则就会被Lua误解析为小数点儿。<br />&nbsp;&nbsp; &nbsp;尽管Lua提供了这种自动转换的功能，为了避免一些不可预测的行为发生，特别是因为Lua版本升级而导致的行为不一致现象。鉴于此，还是应该尽可能使用显示的转换，如字符串转数字的函数<strong><span style="color: #0000ff;">tonumber()</span></strong>，或者是数字转字符串的函数<strong><span style="color: #0000ff;">tostring()</span></strong>。对于前者，如果函数参数不能转换为数字，该函数返回nil。如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> line = <span style="color: #ff00ff; line-height: 1.5 !important;">io.read</span>()<br /><span style="color: #008080; line-height: 1.5 !important;">2</span> n = <span style="color: #ff00ff; line-height: 1.5 !important;">tonumber</span>(line)<br /><span style="color: #008080; line-height: 1.5 !important;">3</span> <span style="color: #0000ff; line-height: 1.5 !important;">if</span> n == <span style="color: #0000ff; line-height: 1.5 !important;">nil</span> <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;">4</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">error</span>(line .. <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;"> is not a valid number</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">5</span> <span style="color: #0000ff; line-height: 1.5 !important;">else</span><br /><span style="color: #008080; line-height: 1.5 !important;">6</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(n * <span style="color: #800080; line-height: 1.5 !important;">2</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">7</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 关于Lua的字符串最后需要介绍的是<strong><span style="color: #0000ff;">"#"</span></strong>标识符，该标识符在字符串变量的前面将返回其后字符串的长度，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> a = <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">hello</span><span style="color: #800000; line-height: 1.5 !important;">"</span><br /><span style="color: #008080; line-height: 1.5 !important;">2</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(#a)</pre></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><span style="color: #0000ff;">&nbsp;&nbsp;&nbsp; /&gt; lua d:/test.lua</span><br /><span style="color: #008000;">&nbsp;&nbsp; &nbsp;5</span><br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp; &nbsp;5. table(表)：</span><br />&nbsp;&nbsp; &nbsp;我们可以将Lua中table类型视为&#8220;关联数组&#8221;，如C++标准库中的map，差别是Lua中table的键(key)可以为任意类型(nil除外)，而map中的键只能为模参类型。此外，table没有固定的大小，可以动态的添加任意数量的元素到一个table中。table是Lua中最主要数据结构，其功能非常强大，可用于实现数组、集合、记录和队列数据结构。以下为table的变量声明，以及关联数据的初始化方式：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> a = {}              <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;"> 创建一个table对象，并将它的引用存储到a</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">2</span> k = <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">x</span><span style="color: #800000; line-height: 1.5 !important;">"</span><br /><span style="color: #008080; line-height: 1.5 !important;">3</span> a[k] = <span style="color: #800080; line-height: 1.5 !important;">10</span>         <span style="color: #008000; line-height: 1.5 !important;">  --</span><span style="color: #008000; line-height: 1.5 !important;"> 创建了新条目，key = "x", value = 10</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">4</span> a[<span style="color: #800080; line-height: 1.5 !important;">20</span>] = <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">great</span><span style="color: #800000; line-height: 1.5 !important;">"</span>     <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;"> 新条目，key = 20， value = "great"</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">5</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(a[<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">x</span><span style="color: #800000; line-height: 1.5 !important;">"</span>])<br /><span style="color: #008080; line-height: 1.5 !important;">6</span> k = <span style="color: #800080; line-height: 1.5 !important;">20</span><br /><span style="color: #008080; line-height: 1.5 !important;">7</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(a[k])         <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;"> 打印great</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">8</span> a[<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">x</span><span style="color: #800000; line-height: 1.5 !important;">"</span>] = a[<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">x</span><span style="color: #800000; line-height: 1.5 !important;">"</span>] + <span style="color: #800080; line-height: 1.5 !important;">1</span><br /><span style="color: #008080; line-height: 1.5 !important;">9</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(a[<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">x</span><span style="color: #800000; line-height: 1.5 !important;">"</span>])      <span style="color: #008000; line-height: 1.5 !important;"> --</span><span style="color: #008000; line-height: 1.5 !important;"> 打印11</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 所有的table都可以用不同类型的索引来访问value，当需要容纳新条目时，table会自动增长。</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> a = {}<br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> i = <span style="color: #800080; line-height: 1.5 !important;">1</span>, <span style="color: #800080; line-height: 1.5 !important;">100</span> <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span>     a[i] = i * <span style="color: #800080; line-height: 1.5 !important;">2</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(a[<span style="color: #800080; line-height: 1.5 !important;">9</span>])<br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span> a[<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">x</span><span style="color: #800000; line-height: 1.5 !important;">"</span>] = <span style="color: #800080; line-height: 1.5 !important;">10</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(a[<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">x</span><span style="color: #800000; line-height: 1.5 !important;">"</span>])<br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(a[<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">y</span><span style="color: #800000; line-height: 1.5 !important;">"</span>])      <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">table中的变量和全局变量一样，没有赋值之前均为nil。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 9</span> <br /><span style="color: #008080; line-height: 1.5 !important;">10</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出结果为</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">11</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">18</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">12</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">10</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">13</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">nil</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 在Lua中还提供了另外一种方法用于访问table中的值，见如下示例：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> a.x = <span style="color: #800080; line-height: 1.5 !important;">10</span>      <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">等同于a["x"] = 10</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">2</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(a.x)    <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">等同于print(a["x"])</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">3</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(a.y)    <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">等同于print(a["y"])</span></pre></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 对于Lua来说，这两种方式是等价的。但是对于开发者而言，点的写法隐式的将table表示为记录，既C语言中的结构体。而之前讲述的字符串表示法则意味着任何字符串均可作为table的key。<br />&nbsp;&nbsp; &nbsp;如果需要将table表示为传统的数组，只需将整数作为table的key即可。如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> a = {}<br /><span style="color: #008080; line-height: 1.5 !important;">2</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> i = <span style="color: #800080; line-height: 1.5 !important;">1</span>,<span style="color: #800080; line-height: 1.5 !important;">10</span> <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">3</span>     a[i] = i * <span style="color: #800080; line-height: 1.5 !important;">2</span><br /><span style="color: #008080; line-height: 1.5 !important;">4</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">5</span> <br /><span style="color: #008080; line-height: 1.5 !important;">6</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> i = <span style="color: #800080; line-height: 1.5 !important;">1</span>,<span style="color: #800080; line-height: 1.5 !important;">10</span> <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">7</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(a[i])<br /><span style="color: #008080; line-height: 1.5 !important;">8</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 在Lua中，我通常习惯以1作为数组索引的起始值。而且还有不少内部机制依赖于这个惯例。如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> a = {}<br /><span style="color: #008080; line-height: 1.5 !important;">2</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> i = <span style="color: #800080; line-height: 1.5 !important;">1</span>,<span style="color: #800080; line-height: 1.5 !important;">10</span> <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">3</span>     a[i] = i * <span style="color: #800080; line-height: 1.5 !important;">2</span><br /><span style="color: #008080; line-height: 1.5 !important;">4</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">5</span> <br /><span style="color: #008080; line-height: 1.5 !important;">6</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> i = <span style="color: #800080; line-height: 1.5 !important;">1</span>,#a <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">7</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(a[i])<br /><span style="color: #008080; line-height: 1.5 !important;">8</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 由于数组实际上仍为一个table，所以对于数组大小的计算需要留意某些特殊的场景，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;a = {}</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;a[1000] = 1</span><br />&nbsp;&nbsp; &nbsp;在上面的示例中，数组a中索引值为1--999的元素的值均为nil。而Lua则将nil作为界定数据结尾的标志。当一个数组含有&#8220;空隙&#8221;时，即中间含有nil值，长度操作符#会认为这些nil元素就是结尾标志。当然这肯定不是我们想要的结果。因此对于这些含有&#8220;空隙&#8221;的数组，我们可以通过函数table.maxn()返回table的最大正数索引值。如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> a = {}<br /><span style="color: #008080; line-height: 1.5 !important;">2</span> a[<span style="color: #800080; line-height: 1.5 !important;">1000</span>] = <span style="color: #800080; line-height: 1.5 !important;">1</span><br /><span style="color: #008080; line-height: 1.5 !important;">3</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #ff00ff; line-height: 1.5 !important;">table.maxn</span>(a))    <br /><span style="color: #008080; line-height: 1.5 !important;">4</span> <br /><span style="color: #008080; line-height: 1.5 !important;">5</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;"> 输出1000</span></pre></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: 15px; color: #800080;">6. function(函数)：</span><br />&nbsp;&nbsp; &nbsp;在Lua中，函数可以存储在变量中，可以通过参数传递其它函数，还可以作为其它函数的返回值。这种特性使语言具有了极大的灵活性。<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #800080; font-size: 15px;">7. userdata(自定义类型)：</span><br />&nbsp;&nbsp; &nbsp;由于userdata类型可以将任意C语言数据存储到Lua变量中。在Lua中，这种类型没有太多预定义的操作，只能进行赋值和相等性测试。userdata用于表示一种由应用程序或C语言库所创建的新类型。</p><img src ="http://www.cppblog.com/mmdengwo/aggbug/205789.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mmdengwo/" target="_blank">沛沛</a> 2014-02-17 17:33 <a href="http://www.cppblog.com/mmdengwo/archive/2014/02/17/205789.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>