• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
    • 軟件測試技術
    • 軟件測試博客
    • 軟件測試視頻
    • 開源軟件測試技術
    • 軟件測試論壇
    • 軟件測試沙龍
    • 軟件測試資料下載
    • 軟件測試雜志
    • 軟件測試人才招聘
      暫時沒有公告

    字號: | 推薦給好友 上一篇 | 下一篇

    LUA學習筆記1-Functions

    發布: 2007-7-04 20:48 | 作者: admin | 來源:  網友評論 | 查看: 76次 | 進入軟件測試論壇討論

    領測軟件測試網

    Function Description

    在LUA中, Function和Number, String一樣屬于基本類型. 凡是基本類型可以出現的地方Function一樣可以出現. 這意味著Function可以存儲在變量中,可以作為另一個Function的參數傳遞,也可以作為某個Function的返回值. 可以把Function德名字視為一種變量,它指向具體的Function實現. 這樣的機制給程序設計帶來了極大的彈性. 一個程序可以重寫某個Function以便給他增加功能, 或者刪除某個函數創建安全運行環境(SandBox).

        a = {p = print}
        a.p("Hello World") --> Hello World
        print = math.sin  -- `print' now refers to the sine function
        a.p(print(1))     --> 0.841470
        sin = a.p         -- `sin' now refers to the print function
        sin(10, 20)       --> 10      20

        function foo (x) return 2*x end 等價于 foo = function (x) return 2*x end

     

    在調用LUA的Function時,所有的參數應該包圍在'('和')'之間, 即使函數沒有參數, '('和')'也不應該被省略.
        print(8*9, 9/8)
        a = math.sin(3) + math.cos(10)
        print(os.date())

    這兒有一種例外情況, 如果Function只有一個參數且這個參數是literal string或者table constructor, 這時大括號keyi省略.
        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 作為額外的參數放到第一個參數的位置.

    Function Definition

    LUA中的函數定義和許多程序設計語言一樣, 需要有一個函數名, 一系列的參數和函數體.
        -- add all elements of array `a'
        function add (a)
          local sum = 0
          for i,v in ipairs(a) do
            sum = sum + v
          end
          return sum
        end

    函數的參數是局部變量, LUA中比較特殊的是調用函數時參數的個數可以和定義時不一樣. LUA會調整參數的個數, 這一點很像多重賦值, 調用函數時所給的多余參數會被丟掉,  調用函數時如果參數不夠后邊的會被賦為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被拋棄)

    這種機制和大多數強類型編成語言(C,C++,Java)不同, 不過這種做法帶來了一些好處:
        function incCount (n)
          n = n or 1
          count = count + n
        end

    這里1作為函數的默認參數, 如果調用時不給參數, 那么n的值就是nil, 否則就是用用戶調用時給的值.


    Multiple Results
    多重返回值是LUA提供的一種并不符合傳統, 但是十分方便的機制. 一些LUA預定義的函數也使用了多重返回值的機制, 例如 string.find 函數, 他的兩個返回值分別表示查找到的字符串的起始和結束位置. 如果沒找到返回值為nil.
        s, e = string.find("hello Lua users", "Lua")   
        print(s, e)   -->  7      9

    使用多重返回值的方法很簡單, 你只需要將返回的變量列舉出來就可以了. 以下的例子函數返回一個數組中的最大值和最大值元素的索引.
       function maximum (a)
          local mi = 1          -- maximum index
          local m = a[mi]       -- maximum value
          for i,val in ipairs(a) do
            if val > m then
              mi = i
              m = val
            end
          end
          return m, mi
        end
       
        print(maximum({8,10,23,12,5}))     --> 23   3


    Variable Number of Arguments
    在LUA中Function支持不定個數的參數, 用 ... 表示. 這和LUA中普通函數的調用是有所區別的. 調用函數時所給參數可以和定義時不同, 但這里其實是LUA編譯器對參數作了自動補足, 調用時參數不夠的話多余的置為nil, 調用時參數過多則將多余的拋棄. 并不是真正的參數個數不定.
        printResult = ""
       
        function print (...)
          for i,v in ipairs(arg) do
            printResult = printResult .. tostring(v) .. "\t"
          end
          printResult = printResult .. "\n"
        end
    這里...表示參數個數不確定, 當print調用時, 所有的參數都被存儲在一個table內, 這個隱藏變量的名字叫arg, 除了函數的參數外, arg還含有一個額外的元素n, 用來表示參數的個數.

    一個Function可以有多個返回值, 有時我們想指定使用返回值中的某一個而忽略其他的, 這時可以用 _ 表示忽略.
        local _, x = string.find(s, p)
        -- now use `x'
        ...

    另一種方法是使用select函數,
        print(string.find("hello hello", " hel"))         --> 6  9
        print(select(1, string.find("hello hello", " hel"))) --> 6
        print(select(2, string.find("hello hello", " hel"))) --> 9

    對于以下情況:
     function g (a, b, ...) end

    調用結果如下:
        g(3)             a=3, b=nil, arg={n=0}
        g(3, 4)          a=3, b=4, arg={n=0}
        g(3, 4, 5, 8)    a=3, b=4, arg={5, 8; n=2}

    Named Arguments
    在LUA中, 如果一個函數有許多參數而且大多數參數都是可選的話, 將參數定義為table會帶來一些額外的方便性, 你不需要記住參數的位置, 只需要記住參數的名字即可.

    例如一個產生窗口的函數可能有許多參數,
        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

     

    調用時很簡單, 你只需要給出參數的名字和值, 順序無關緊要.
        w = Window{ x=0, y=0 }

    Closure
        Function屬于基本類型, 所以一個Function可以返回另一個Function.
       function foo()
               return function() return end
       end
       
       c1 = foo()  --> 每次調用返回一個匿名的function對象.
       c2 = foo()
       
       print(c1)  --> function: 0x87dd470
       print(c2)  --> function: 0x87dd490
        c1和c2是不同的對象.

        同樣, 如果一個作為返回值的函數對象內使用了上層的局部變量, 每一個返回的函數對象內使用的這個局部變量都是不同的. 這種情況稱作closure.
       
       function foo()
           local x=10
           return function()
               x=x+1
               return x end
       end
       
       c1 = foo()  --> 每次調用返回一個匿名的function對象.
       c2 = foo()

       print(c1)               --> function: 0x87dd470
       print(c2)               --> function: 0x87dd490
       
       print(c1())  --> 11
       print(c1())  --> 12
       print(c2())  --> 11
       print(c1())  --> 13
       print(c2())  --> 12

       
    Proper Tail Calls
    Proper Tail Calls是LUA的另一個有趣的特性, 在一個LUA函數中, 如果最后一個操作是返回一個函數調用, 例如 return g(...), 那么LUA不會把它當作一個函數調用而建立調用堆棧而只簡單的跳轉到另一個函數中.
     function foo (n)
          if n > 0 then return foo(n - 1) end
     end
    這個函數無論n是多大都不會發生堆棧溢出, 這里return foo(...)的功能相當于goto.
    以下調用并不是Tail Calls, 因為函數調用返回后還作了其他的操作:
        return g(x) + 1     -- must do the addition
        return x or g(x)    -- must adjust to 1 result
        return (g(x))       -- must adjust to 1 result

    在LUA中, 只有形如return g(...)是tail call. 然而g和他的參數可以是復雜的調用形式, 因為LUA會先計算表達式的值然后調用函數, 所以下面是一個tail call.
          return x[i].foo(x[j] + a*b, i + j)

    延伸閱讀

    文章來源于領測軟件測試網 http://www.kjueaiud.com/


    關于領測軟件測試網 | 領測軟件測試網合作伙伴 | 廣告服務 | 投稿指南 | 聯系我們 | 網站地圖 | 友情鏈接
    版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved
    北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備2023014753號-2
    技術支持和業務聯系:info@testage.com.cn 電話:010-51297073

    軟件測試 | 領測國際ISTQBISTQB官網TMMiTMMi認證國際軟件測試工程師認證領測軟件測試網

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>