命名参数,有的翻译为具名参数,顾名思义就是给带入函数的参数起个名字,注意这个名字是固定的。我们知道一般的语言,比如c/c++,java等参数只有在函数定义的时候才有类型和变量名,在函数调用时传入的是变量名或者实际值,这里的变量名可以相同也可以不同。

// 假定有函数squire
int squire(int length, int width);

// 我们调用是可以如下调用,带入的变量名可以使a,b,也可以是length,width
// 还可以直接是值,这些参数是非命名参数,只要类型一致,名字没有要求
int a=10, b=20;
int length=10, width=20;
squire(a,b);
squire(length, width);
squire(10,20);

如果函数的需要传入的参数很多,直接摊开就显得函数非常笨拙,而且调用者容易忘记函数参数类型,顺序和个数,这样的设计不符合函数设计的风格;所以c语言可以使用结构体来包含这些参数,c++有结构体和类,这样就优化了函数的设计,以c语言为例

#define  Chinese   0
#define  Math      1
#define  English   2
#define  Music     3
#define  Male    0
#define Female   1
struct Student
{
   char name[20];
   int age;
   int sex;
   int grade;
   int subject;

};

// 下面的函数是查询某个学生的学科成绩
int GetStudentScore(struct Student *student);

// 显然这个函数要比下面的函数简洁,
int GetStudentScore(char *name, int sex, int grade, int subject);

有人会说例子为什么不用学号,用学号就不用姓名,性别和年级了,呵呵,这里仅仅举例,假定没有学号。上面的例子显然age是用不上的。lua没有结构体,但有比结构体更加灵活的表table,lua中可以将这些参数通通放到表中,用表作为函数的参数,表中的各个参数附上成员名字,这样就简单化了,尤其是在有很多参数是可选时的场合。

下面以《Program in lua》书中的例子和另外一个简单例子来说明,需要提一下,我查看了两个翻译中文的版本,在对原文例子的描述中都存在错误;如果你安装中文翻译的来学习,使用书中例子时可能会出错。

英文原版书中的例子

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, width=300, height=200,
  title = "Lua", background="blue",
  border = true
}

由于书中缺少_Window函数的定义,所以是编译不过的;这里只是为了说明,Window函数带入的参数options,是表类型,此表包含需要的参数;而在此函数只关注title、width和height三个强制性参数,其他的都是可选的参数,继续调用_Window来完成功能,这样的函数设计简单又清晰。在用w=Window{…}调用函数时,就可以按照定义输入相关参数,其他的可以不选可不选。下面给一个可以执行的例子

function bonus(quantity, price, rate)
      return quantity * price * rate;
end

function SalerBonus(saler)
     if type(saler.name) ~= "string" then
         print("no name");
     elseif type(saler.sex) ~= "string" then
         print("no sex");
     elseif type(saler.age) ~= "number" then
         print("no age");
     end

     return bonus(saler.quantity or 20, 
                  saler.price or 10, 
                  saler.rate or 0.1);
end


print("Tony's bonus is "..SalerBonus{name="Tony", 
sex="male", age=20}.."$");

print("Andy's bonus is "..SalerBonus{name="Andy", 
sex="female", age=25, quantity=50, price=20, rate=0.15}.."$");

执行结果如下

Tony's bonus is 20$
Andy's bonus is 150$

售货员Tony卖的是大路货,而且是吃大锅饭的,所以奖金只有20$,Andy卖的是利润高的商品,卖的也多,提成比也高,所以奖金是150$。

下面是中文翻译版的截图,如果安装图中的例子去操作是会失败的

lua 引用io库 lua 引用参数_lua


函数调用应该放在后面的,否则会报错,调用了nil的类型;英文原版就没有这个问题,所以建议学习时,如果出现异常,对照一下英文原版。