<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                在Lua中,函數是對語句和表達式進行抽象的主要方法。既可以用來處理一些特殊的工作,也可以用來計算一些值。下面有3個例子,分別將函數當作一條語句;當作表達式(后面兩個是一類)。 ~~~ print(8*9, 9/8) --> 72 1.125 a = math.sin(3) + math.cos(10) --> a = -0.69795152101659 print(os.date()) --> Sat Mar 9 12:14:08 2013 ~~~ 函數如果帶參數,那么就要用(arg1, arg2,...)括起來,如果沒有參數,就寫個空(),說明這是個函數調用。 特例,如果函數只有一個參數,并且參數類型是字符串或者table,那么()可以省略,如下示例: ~~~ print "Hello World" <==> print("Hello World") dofile 'a.lua' <==> dofile('a.lua') print[[a multi-line <==> print([[a multi-line message]] message]]) f{x=10, y=20} <==> f({x=10, y=20}) type{} <==> type({}) ~~~ Lua支持面向對象,操作符為冒號‘:’。o:foo(x) <==> o.foo(o, x),這個在后面會專門寫一篇文章。 Lua程序可以調用C語言或者Lua實現的函數。Lua基礎庫中的所有函數都是用C實現的。調用一個用C實現的函數,和調用一個用Lua實現的函數,二者沒有任何區別。 Lua函數的定義語法比較常規,如下示例: ~~~ function add(a) local sum = 0 for i, v in ipairs(a) do sum = sum + v end return sum end ~~~ 函數的參數跟局部變量一樣,用傳入的實參來初始化,多余的實參被丟棄,多余的形參初始化為nil。示例如下: ~~~ function f(a, b) return a or b end f(3) -- a=3, b=nil f(3, 4) -- a=3, b=4 f(3, 4, 5) -- a=3, b=4 (5被丟棄) ~~~ 雖然Lua可以處理這樣的情況,但是不鼓勵這種傳入錯誤數量參數的函數調用,可能會使程序運行時有點小問題。不過,有些情況下,這個特性可以加以利用,例如下面示例的默認參數: ## 1.多返回值 不同于常規函數,Lua的函數可以返回多個返回值。一些Lua中預定義的函數可以返回多個返回值。例如*string.find*函數,在string中匹配一個sub-string,*string.find*返回sub-string的起始位置和結束位置。利用多賦值語句來獲取函數的多個返回值。 用Lua寫的函數也可以返回多個返回值,如下示例,查找array中的最大值,并返回其位置和值 Lua會根據實際情況來使函數的返回值個數適應調用處的期望。 1)如果一個函數調用作為一條語句,所有的返回值都被丟棄 2)如果一個函數調用作為一個表達式,除了3)的情況,返回值只保留第一個 3)在多賦值,返回值作為實參來調用其他函數,table中,return語句中,這4種調用場景,如果函數調用作為其最后一個表達式,那么會保留所有的返回值,然后根據實際調用需要再糾正。 示例: ~~~ -- 多賦值,函數調用是最后一個表達式 x,y = foo2() -- x="a", y="b" x = foo2() -- x="a", "b" is discarded x,y,z = 10,foo2() -- x=10, y="a", z="b" x,y = foo0() -- x=nil, y=nil x,y = foo1() -- x="a", y=nil x,y,z = foo2() -- x="a", y="b", z=nil -- 多賦值,函數調用不是最后一個表達式,因此返回值只保留第一個 x,y = foo2(), 20 -- x="a", y=20 x,y = foo0(), 20, 30 -- x=nil, y=20, 30 is discarded -- 返回值作為實參來調用其他函數 print(foo0()) --> print(foo1()) --> a print(foo2()) --> a b print(foo2(), 1) --> a 1 print(1, foo2()) --> 1 a b print(foo2() .. "x") --> ax (see next) -- table中 t = {foo0()} -- t = {} (an empty table) t = {foo1()} -- t = {"a"} t = {foo2()} -- t = {"a", "b"} -- table中,但是函數調用不是最后一個表達式 t = {foo0(), foo2(), 4} -- t[1] = nil, t[2] = "a", t[3] = 4 -- return語句中 function foo (i) if i == 0 then return foo0() elseif i == 1 then return foo1() elseif i == 2 then return foo2() end end print(foo(1)) --> a print(foo(2)) --> a b print(foo(0)) -- (no results) print(foo(3)) -- (no results) ~~~ 用括號來強制返回值個數為一個: ~~~ print((foo0())) --> nil print((foo1())) --> a print((foo2())) --> a ~~~ 因此,括號千萬別亂用,尤其是return后的值,如果用了括號,那么就只返回一個值。 函數unpack可以返回多個值,它傳入一個array,然后返回array中的每一個值。 ~~~ print(unpack{10,20,30}) --> 10 20 30 a,b = unpack{10,20,30} -- a=10, b=20, 30 is discarded ~~~ unpack的一個重要用法是泛型調用,提供了比C語言中更大的靈活性。在Lua中,如果你想調用一個函數*f,*傳入可變數量的參數,很簡單, ~~~ f(unpack(a)) ~~~ unpack返回a中的所有值,并傳給*f?*作為參數,下面示例: ~~~ f = string.find a = {"hello", "ll"} print(f(unpack(a))) --> 3 4 ~~~ Lua中的unpack是用C實現的。其實我們也可以用Lua來實現它 ~~~ function unpack (t, i) i = i or 1 if t[i] then return t[i], unpack(t, i + 1) end end ~~~ ## 2. 變參 Lua中的一些函數接受可變數量的參數,例如print函數。print函數是用C來實現的,但是我們也可以用Lua來實現變參函數。下面是一個示例: ~~~ function add (...) local s = 0 for i, v in ipairs{...} do s = s + v end return s end print(add(3, 4, 10, 25, 12)) --> 54 ~~~ 參數列表中的'...'指明該函數可以接受變參。我們可以將‘...’當作一個表達式,或者一個多返回值的函數(返回當前函數的所有參數)。例如 ~~~ local a, b = ... ~~~ 用可選參數的前兩個初始化局部變量a,b的值。再看下面的例子, ~~~ function foo(a, b, c) <==> function foo(...) local a, b, c = ... ~~~ ~~~ function id (...) return ... end ~~~ 上面這個函數簡單地返回它所有的參數。下面的例子,說明了一個跟蹤函數調用的技巧 ~~~ function foo1 (...) print("calling foo:", ...) return foo(...) end ~~~ 再看一個實用的例子。Lua提供了不同的函數來格式化文本*string.formant*和寫文本*io.write*,我們可以簡單地將二者合二為一。 ~~~ function fwrite (fmt, ...) return io.write(string.format(fmt, ...)) end ~~~ 注意有一個固定的參數fmt。變參函數可能含有不定數目的固定參數,后面再跟變參。Lua會將前面的實參賦值給這些固定參數,剩下的實參才能當作變參看待。下面是幾個示例: ~~~ CALL PARAMETERS fwrite() -- fmt = nil, no varargs fwrite("a") -- fmt = "a", no varargs fwrite("%d%d", 4, 5) -- fmt = "%d%d", varargs = 4 and 5 ~~~ 如果想要迭代處理變參,可以用{...}來將所有的變參收集到一個table中。但是有時變參中可能含有非法的*nil*,我們可以用*select*函數。*select*函數有一個固定的參數*selector*,然后跟一系列的變參。調用的時候,如果*selector*的值為數字n,那么select函數返回變參中的第n個參數,否則*selector*的值為'#',*select*函數會返回可變參數的總數目。下面示例: ~~~ for i=1, select('#', ...) do local arg = select(i, ...) -- get i-th parameter <loop body> end ~~~ 注意,select("#", ...)返回變參的數目,包括nil在內。 ## 3. 帶名字的參數 Lua中函數的參數傳遞是基于位置的,當調用函數的時候,實參根據位置來匹配形參。但是,有的時候,根據名字來匹配更實用。例如,系統函數*os.rename*,我們會經常忘記新名字和舊名字哪個在前;為了解決這個問題,我們嘗試重新定義這個函數。下面這個 ~~~ -- invalid code rename(old="temp.lua", new="temp1.lua") ~~~ 上面這個代碼是非法的,Lua并不支持這樣的語法。但是我們可以修改一點點,來實現相同的效果。 ~~~ function rename (arg) return os.rename(arg.old, arg.new) end ~~~ 用這種方式來傳遞參數是很實用的,尤其是,當函數有多個參數,并且其中一些是可有可無時。例如,用GUI庫創建一個新的窗口 ~~~ w = Window{ x=0, y=0, width=300, height=200, title = "Lua", background="blue", border = true } ~~~ *Window*函數可以檢查必須的參數,并且給可選參數賦予默認值等。假設*_Window*函數可以用來創建一個新窗口,但是它必須要全部的參數。那我們就可以重新定義一個*Window*函數如下: ~~~ function Window (options) -- check mandatory options if type(options.title) ~= "string" then error("no title") elseif type(options.width) ~= "number" then error("no width") elseif type(options.height) ~= "number" then error("no height") end -- everything else is optional _Window(options.title, options.x or 0, -- default value options.y or 0, -- default value options.width, options.height, options.background or "white", -- default options.border -- default is false (nil) ) end ~~~ 水平有限,如果有朋友發現錯誤,歡迎留言交流。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看