zoukankan      html  css  js  c++  java
  • lua 3

    函数

    Lua为面向对象式的调用也提供了一种特殊的语法——冒号操作符。表达式o.foo(o,x)的另一种写法是o:foo(x),

    冒号操作符使调用o.foo时将o隐含地作为函数的第一歌参数。

    一个Lua程序既可以使用以Lua编写的函数,又可以调用以C语言编写的函数。

    function incCount(n)

    n=n or 1

    count = count+n

    end

    多重返回值

    Lua具有一项非常与众不同的特征,允许函数返回多个结果。Lua的几个预定义函数就是返回多个值的。

    Lua的几个预定义函数就是返回多个值的。例如,用于在字符串中定位一个模式(pattern)的函数string.find。

    该函数若在字符串中找到了指定的模式,将返回匹配的起始字符和结尾字符的索引。在此就需要使用多重赋值

    语句来接收函数的返回值。

    s,e=string.find("hello Lua users", "Lua")

    print(s,e)-->7  9

    以Lua编写的函数同样可以返回多个结果,只需要在return关键字后列出所有的返回值即可。例如,需要写一个

    函数用于查找数组中的最大元素,并返回该元素的位置:

    function maximum(a)

    local mi=1

    local m=a[mi]

      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}))

    Lua会调整一个函数的返回值数量以适应不同的调用情况。

    变长参数

    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

    参数表中的3个点(...)表示该函数可以接受不同数量的实参。当这个函数被调用时,它的所有参数都会被

    收集到一起。这部分收集起来的实参称为这个函数的“变长参数”。一个函数要访问它的变长参数时,仍需

    用到3个点(...)。但不同的是,此时这3个点是作为一个表达式来使用的。在上例中,表达式{...}表示一
    个由所有变长参数构成的数组。而函数add遍历了该数组,并累加了每个元素。
      表达式“...”的行为类似于一个具有多重返回值的函数,它返回的是当前函数的所有变长参数。例如:
      local a,b=...用第一个和第二个变长参数来初始化这两个局部变量。实际上,还可以通过变长参数
    来模拟Lua中普通的参数传递机制,例如:
      function foo(a,b,c)
    可以转换为:
      function foo(...)
      local a,b,c=...
      end
    对于哪些喜爱Perl参数传递机制的人来说,可能会更倾向于第二种形式。
    若有这样一个函数:
      function id(...)  return ... end
    它只是简单地返回调用它时传入的所有实参,这是一个“多值恒定式”函数。下这个函数的行为非常类似于
    直接调用函数foo,但在调用foo前先调用print打印出其所有的实参:
      function foo1(...)
      print("calling foo:",...)
        return foo(...)
      end
      这种技巧对于跟踪某个特定的函数调用很有帮助。
      Lua提供了专门用于格式化文本(string.format)和输出文本(io.write)的函数。很自然地会想到将函数
    合二为一:
      function fwrite(fmt,...)
      return io.write(string.format(fmt,...))
      end
    注意在3歌点前有一个固定参数fmt。具有变长参数的函数同样也可以拥有任意数量的固定参数,但固定参数必须放在变长参数之前。Lua会将前面的实参赋予固定参数,而将余下的实参视为变长参数。
      通常一个函数在遍历其变长参数时只需要使用表达式{...},这就像访问一个table一样,访问所有变长参数。然而在
    某些特殊的情况下,变长参数中可能包含一些故意传入的nil,那么此时就需要用函数select来访问变长参数了。调用select时,必须传入一个固定实参selector(选择开关)和一些列变长参数。如果selector位数字n,那么select返回它的第n个可变实参;否则,selector可能为字符串“#”,这样select会返回变长参数的总数。下面的循环演示了如何使用select来遍历一个函数的所有变长参数:
      for i=1,select('#',...) do
      local arg=select(i,...)
      end
      select("#",...)会返回所有变长参数的总数,其中包括nil。

    具名实参
      Lua中的参数传递机制是具有“位置性”的,也就是说在调用一个函数时,实参是通过它在参数表中的位置与形参匹配
    起来的。第一个实参的值与第一个形参相匹配,依次类推。但有时通过名称来指定实参也是很有用的。
      os.rename,这个函数用于文件改名。通常会忘记第一个参数是表示新文件名还是旧文件名。因此,会希望这个函数能够接受两个具有名称的实参。
      rename{old="temp.lua",new="temp1.lua"}
      另一方面,将rename改为只接受一个参数,并从这个参数中获取实际的参数:
      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)
      if type(options.titile) ~= "string" then
        error("no title")
      elseif type(options.width) ~= "number" then
        error("no width")
          elseif type(options.height) ~= "number" then
        error("no height")
      end
      --其他参数都是可选的
      _Window(options.title,
            options.x or 0
            options.y or 0
            options.width,options.height,
              options.background or "white",
              options.border)
      end

  • 相关阅读:
    矩阵快速幂
    快速排序
    用闭包来实现命令模式
    闭包和面向对象设计
    闭包及其作用
    阿里笔试
    如何在节点上添加样式
    getComputedStyle与currentStyle获取样式(style/class)
    今日头条笔试
    牛客网JavaScript编程规范
  • 原文地址:https://www.cnblogs.com/wendao/p/lua_note_3.html
Copyright © 2011-2022 走看看