IT教程 ·

lua进修之温习汇总篇

第六日笔记

1. 基本观点

程序块

定义

  1. 在 lua 中任何一个源代码文件或在交互形式中输入的一行代码
  2. 程序块可所以恣意大小的
  3. 程序块可所以一连串语句或一条敕令
  4. 也可由函数定义构成,平常将函数定义写在文件中,然后用诠释器实行这个文件
  5. 换行在代码中不起任何作用,只是为了提拔可读性
  6. 分开符 ; 起分开作用
a = a * 2 
b = a * b

a = a * 2;
b = a * b

a = a * b; b = a * b
a = a * b b = a * b

交互形式

在交互形式中输入的一行内容会被诠释器看成一个完全的程序块,假如这一行的内容不足以构成一个完全的程序块,就会守候输入

退出交互形式
  1. Ctrl + Z 是 end-of-file 掌握字符,在 dos 中是这个快捷键
  2. os.exit() 规范库中的退出函数

地区设置

  1. lua 中辨认什么是字母是经由历程地区设置来鉴别的
  2. 如设置希腊,就能够辨认希腊字母作为变量
  3. 但在不支撑该地区的体系上没法实行

实行函数文件

  1. lua 函数文件途径
  2. dofile("文件途径 / 须要转义") 加载函数库
-- 阶乘函数
function fact(n) 
    if n == 0   then
        return 1 --0 的阶乘是 1
    else
        return n * fact(n - 1) -- 3 的阶乘, 3 * 2 * 1
    end
end
print("Enter a number:")
a = io.read("*number")  -- 读取用户输入且需为数字范例的
print(fact(a)) --挪用阶乘函数,并传入实参 a 

-- lib1 函数库
function norm(x, y)
    return (x ^ 2 + y ^ 2) ^ 0.5  -- 两个数的平方和再开平方根
end
function twice(x)
    return 2 * x -- 一个数的两倍
end

标识符

定义

  1. 由恣意数字、字母、下划线构成的字符串叫做标识符
  2. 标识符不能由数字开头
  3. 标识符不能以下划线开头后跟多个大写字母
  4. 如: _PROMPT, _VERSION
  5. lua 将它们保存用作特别用处,被称为哑变量
_PROMPT = ">lua"  -- 修正交互形式中的提示符,默以为 >

保存字

流程掌握
  1. if
  2. then
  3. elseif
  4. end
  5. for
  6. do
  7. in
  8. while
  9. repeat
  10. until
if 前提表达式 then
    elseif 前提表达式 then
end
for 掌握变量, 停止变量, 步长 do
    <轮回体>
end
a = {}
for i,v in ipairs(a) do
    <轮回体>
end
while i < 10 do
    i = i + 1
    print(i)
end
repeat
    i = 0
    i = i + 1
until i > 10
前提掌握
  1. true
  2. false
逻辑掌握
  1. and
  2. or
  3. not
范例
  1. function
  2. local
  3. nil
须要注重的点
  1. nil == nil 是相称的
  2. andAnd 差别,lua 辨别大小写
  3. lua 中前提值不单单议只要 truefalse
  4. 在 lua 中任何值除了 falsenil 都能够用作示意「真」
  5. 包括空字符串 "" 和数字 0

解释

  1. 单行解释 --
  2. 多行解释 --[[]]
  3. 使多行解释中的代码见效 ---[[ <代码块> --]]
  4. 多行解释中包括多行解释 --[==[ <多行解释> ]==]

全局变量

  1. 全局变量不须要声明,只须要将一个值赋给它即可
  2. lua 中能够接见一个未初始化的变量且不会发作毛病
  3. 但这个未初始化的变量的值为 nil
  4. 删除全局变量赋值 nil 即可
  5. lua 将全局变量存储在一个一般的 table 中

诠释器

参数

  1. -i 先实行程序块,后进入交互形式
  2. -e 直接实行代码块
  3. -l 加载库文件

诠释器实行参数前

  1. 会先寻觅一个叫做 LUA_INIT 的环境变量
  2. 找到了,且内容为 @文件名 的话,就实行这个文件
  3. 没找到,就假定内容为 lua 代码, 并实行

诠释器运转剧本前

  1. lua 将剧本前的参数存储到 arg 这个 table 中,用作启动参数
  2. 剧本名在这个 table 中的索引为 0,厥后参数依此类推
  3. 剧本名前的参数为负数索引
lua -i -e "hello" script a b 
arg[0] = "script"
arg[1] = "a"
arg[-1] = "hello"
arg[-2] = "-e"
arg[-3] = "-i"
  1. 在 lua 中也能够经由历程变长参数语法来检索剧本参数
  2. 变长参数为 ... 三个点,作为函数参数通报时示意通报一切参数

2. 范例与值

  1. lua 是动态范例言语
  2. 每一个值都照顾有它的范例信息

猎取值的范例

  1. type() 能够返回一个值的范例称号
  2. type()的返回结果永远是 string 范例的
print(type(3)) -- number
print(type("a")) -- string
print(type({"a", "b", "c"})) -- table
print(type(io.read)) -- function
print(type(true)) -- boolean

number

  1. 实数,即双精度浮点数
  2. 可运用科学计数法,如 2e2 示意 200
  3. 可从新编译 lua,运用其他范例的值来示意数字范例,如 long
  4. tonumber() 用于将一个字符串显式的转换为数字范例

boolean

  1. 在 lua 中,有两个布尔值一个是 true 示意为「真」,一个是 false 示意为「假」
  2. 但,这两个值不是用来示意前提的唯一值,在 lua 中 除 nilfalse 外的任何值,都能够用来示意

    「真」, 包括空字符串 "" 和数字 0

nil

  1. 只要一个值,nil
  2. 仅用来示意为空,示意未初始化的变量或 table 元素
  3. 也可用来删除变量或 table 元素

string

  1. 是对象,由自动内存接纳器举行分派和开释
  2. 是字符序列,是8位编码
  3. 能够包括数值编码,如二进制
  4. lua 中的字符串是唯一不可变的值
  5. .. 字符串衔接符,用于衔接两个字符串,但数字范例运用时须要用空格离隔
  6. # 长度操纵符,后跟字符串,能够猎取字符串长度
  7. [[]] 在期内的特别字符不须要转义
  8. [==[ <多行解释> ]==] 能够准确打印多行解释的内容
  9. "3" + 4 如许的值会是 number 范例,发作了运转时隐式转换
print("97" == "a") -- 在 ASCII 编码表中,97 示意为 a
print(type(3 .. "")) -- string
print(3..4) --报错
print(3 .. 4) -- 34
print(#"hello") -- 5

-- 猎取子串,证实字符串是不可变的值
a = "hello"
b = a .. " ,world"
print(a) -- hello
print(b) -- hello, world
a = [[
    <html>
        <head><title>芜湖</title></head>
        <body></body>
    </html>
]]
a = [==[
    --[[
        print("多行解释")
        print("多行解释")
    ]]
]==]
print(type("3" + 4)) -- number

显式转换为字符串

  1. tostring()
  2. .. "" 恣意数字衔接一个空字符串即可转换为字符串

table

  1. 是对象,由自动内存接纳器举行分派和开释
  2. table 没有牢固大小,能够动态增加元素
  3. {} 是 table 构造式,用来建立一个 table
  4. # 长度操纵符能够猎取 table 的大小
  5. table 中的元素在未被初始化前都是 nil
  6. 能够将 table 中的元素赋值 nil 来举行删除
  7. 假如 table 中心部份的元素值为 nil 就申明这是一个有「闲暇」的 table
  8. 有「闲暇」的 table 要运用 table.maxn() 来返回这个函数的最大正索引数
  9. table 能够用来示意模块、包、对象
  10. table 中的索引可所以任何值,除了 nil
  11. table 是匿名的
  12. 程序仅保存了对 table 的一个援用
  13. 一个唯一 table 的变量和 table 本身并没有关联
  14. a.x 等价于 a["x"]以字符串为索引的
  15. a[x] 是以变量 x 为索引的
a = {}
for i = 1, 10 do
    a[i] = i
    print(a[i])
end
for i = 1, #a do
    print(a[i])
end
print(a[10]) -- 10
print(#a) -- 10
a[10] = nil
print(#a) -- 9
a[10000] = 666
print(#a) -- 9
print(table.maxn(a)) -- 10000
a = {}
b = {}
c = a 
print(type(a == b)) -- false
print(type(a == c)) -- true
x = "y"
a["x"] = 666
a["y"] = 777
print(a.x) --666
print(a[x]) -- 777

function

  1. 第一类值
  2. 能够存储在变量中
  3. 能够作为函数的返回值或参数
  4. lua 能够挪用本身编写的函数也能够挪用 C 言语编写的函数
  5. lua 规范库中的函数都是用 C 言语编写的

userdata

  1. 由应用程序或 C 言语编写建立的新范例
  2. 没有太多的预定义操纵
  3. 仅用来做赋值和前提测试

3. 表达式

定义

  1. 表达式用于示意值
  2. 在 lua 中,函数挪用,函数定义,数字常量、字面字符串,变量,一元和二元操纵符,table 构造式都是表达式

算数操纵符

一元操纵符

  1. - 负号

二元操纵符

  1. +
  2. - 减号
  3. *
  4. /
  5. %
  6. ^
-- % 的技能
-- x % 1
print(3.13 % 1) -- 获得小数部份
-- x - x % 1
print(3.14 - 3.14 % 1) -- 获得整数部份
-- x - x % 0.1
print(3.14 - 3.14 % 0.1) -- 获得整数部份 + 一名小数部份
-- x - x % 0.01 以此类推,是整数部份 + 两位小数部份

关联操纵符

  1. >
  2. <
  3. >=
  4. <=
  5. == 相称性推断
  6. ~= 不等性推断

逻辑操纵符

  1. and 第一个操纵数为假,返回第一个,不然返回第二个
  2. or 第一个操纵数为真,返回第一个,不然返回第二个
  3. not 只会返回 truefalse
-- 短路操纵的运用技能
print(x = x or v) -- 初始化一个值,假如 x 为 nil 没有被初始化过,就赋值 v 
-- 等价于
if not x then 
    x = v
end
-- 完成 C 言语中的三元操纵符, a ? b : c
print((a and b) or c) -- b 必需为真,才能够如许操纵
-- 等价于
if a == true then
    return b
elseif a == false then
    return c
end
-- 完成返回两个数中的较大值
max = (x > y) and x or y -- 由于 lua 将数字视为「真」
-- 等价于
if x > y then
    return x
else
    return y
end

字符串衔接

  1. .. 字符串衔接

优先级

1级优先

  1. ^

2级优先

  1. - 负号
  2. not
  3. #

3级优先

  1. *
  2. /
  3. %

4级优先

  1. +
  2. - 减号

5级优先

  1. .. 字符串衔接

6级优先

  1. >
  2. <
  3. >=
  4. <=
  5. ==
  6. ~=

7级优先

  1. and

8级优先

  1. or

table 构造式

  1. lua 规范库中的函数对 table 的索引都是从 1 入手下手处置惩罚的

纪录作风的 table

a = {x = 10, y = 20} -- 等价于 a.x = 10, a.y = 20

夹杂运用的 table

  1. 这类体式格局的 table 不能以负数和操纵符作为索引
a = {
    color = {"red", "green", "blue"}
    width = 200,
    height = 300
}

链表

  1. 由一系列节点构成,节点就是元素
  2. 节点能够再运转时动态生成
  3. 每一个节点包括两部份
    1. 存储数据的数据域
    2. 存储下一个地点节点的指针域
list = nil
for line in io.lines() do
    list = {next = list, value = line}
end
local l = list
while l do
    print(l.value)
    l = l.next
end

指定索引的 table

options = {["+"] = "add", ["-"] = "sub", 
    ["*"] = "mul", ["/"] = "div"}
print(options["+"]) -- "add"

4. 语句

  1. 在 lua 中包括赋值,程序构造和历程挪用
  2. 另有多重赋值和局部变量声明

赋值

  1. lua 支撑多重赋值,即 a, b = 1, 2
  2. 会先盘算等号右侧一切元素的值,然后再赋值
  3. 假如右侧的值少于左侧变量,未被初始化的变量就置为 nil
  4. 假如左侧变量少于右侧的值,过剩的值会被「扬弃」
  5. 可用来网络函数的多个返回值
  6. 初始化变量就是为每一个变量赋一个初始值
a, b = 1, 2
x, y  = y, x -- 交流变量
a, b = 1 -- a = 1, b = nil
a, b = 1, 2, 3 -- a = 1, b = 2, 3 被扬弃
a, b = f() -- a 吸收函数 f 的第一个返回值,b 吸收第二个
a, b, c = 0, 0, 0 -- 初始化赋值

局部变量与块

  1. 一个块就是程序构造的实行体,或函数的实行体
  2. 在块内声明的变量仅在块内见效,即作用域为声明它们的块
  3. 可显式声明一个块运用 do <要实行的内容> end 将要实行的内容包裹在一个块内

局部变量

  1. local 用来声明一个局部变量
  2. 局部变量仅在声明它的块内见效,在块的外部无效
  3. 如:在轮回内部声明在的变量在轮回外部则没法运用
a = 3
b = 0
if a then
    local a = 5
    b = a -- 将 then 块内的局部变量 a ,保存到全局变量 b 中
    print(a)
end
print(a) -- 3
print(b) -- 5
do
    -- code block
end

只管运用局部变量

  1. 运用局部变量要比全局变量要快
  2. 防止污染全局环境
  3. 局部变量仅在声明它的块中有用,即在块外这个变量就被开释掉了
  4. lua 将局部变量声明看成语句处置惩罚,即能够在任何支撑誊写语句的处所誊写局部变量声明
  5. 声明能够包括初始化赋值

程序构造

  1. 程序构造中的前提表达式可所以任何值

前提构造

  1. if
  2. elseif
  3. else
if 前提表达式 then 
    <实行体> -- 相符前提表达式实行
end
if 前提表达式1 then
    <实行体 1> -- 相符前提表达式 1 实行
    elseif 前提表达式2 then
    <实行体 2> -- 相符前提表达式 2 实行
end
if 前提表达式 then
    <实行体 1>  -- 前提表达式为真时实行
else
    <实行体 2>  -- 前提表达式为假是实行
end

轮回构造

  1. for
  2. while 前提表达式为时退出
  3. repeat ... until 前提表达式为时推出,前提测试是在轮回体以后做的,因而轮回体最少会实行一次
  4. 在轮回体内声明的局部变量的作用域包括了前提测试
  5. 轮回的三个表达式是在轮回入手下手前一次性求值的
  6. 掌握变量会被自动声明为 for 块中的局部变量,即作用域为 for 块,在轮回完毕后不可见
  7. 不要在轮回历程当中修正掌握变量的值
  8. 能够运用 breakreturn 在轮回一般完毕前提前完毕它
for exp1, exp2, exp3 do
   <轮回体> 
end
while 前提表达式 do
    <轮回体>
end
repeat 
    <轮回体>
until 前提表达式
a = 20
repeat
    local a = 0
    print(a)
until a == 0 -- 可接见在 repeat 块内声明的 a, 而不是全局变量 a 
数值型 for
for i = 10, 0, -1 do
    print(i)
end
泛型 for
  1. ipairs() 用来遍历数组
  2. i 每次轮回时都邑给予一个新的索引值,v 则是索引值所对应的元素
a = {1, 2, 3, 4, 5, 6}
for i,v in ipairs(a) do 
    print(i)
    print(v)
end
for i,v in pairs(a) do
    print(i)
    print(v)
end
两种 for 的共同点
  1. 轮回变量都是轮回体的局部变量
  2. 不应该对轮回遍历举行赋值
days = {"第一天", "第二天", "第三天"}
revdays = {}
for i, v in ipairs(days) do
    revdays[v] = i -- 逆向数组,将数组索引和数组元素换取,可猎取数组元素的位置
end
print(revdays["第二天"]) -- 猎取第二天所在位置

break 和 return

  1. break 用于完毕一个轮回,跳出内层轮回后在外层轮回中继承实行
  2. return 用于返回函数结果或简朴的完毕函数的实行
  3. 任何函数的末端处现实都有一句隐式的 return
  4. 假如函数无返回值,就无需在末端处加 return

二者的共同点

  1. 都是用作跳出当前块
  2. 都须要放在一个块的末端处,即一个块的末了一条语句
  3. 由于 returnbreak 后的语句将没法实行到
  4. 能够用 do ... end 块包裹 return,用与调试,即挪用函数但不实行函数内容的状况
a = 1
if a then
   print("hello")
   break
   print("world") -- 会报错
end
for i = 1, 10 do
    print(i)
    if i > 3 then
        break -- 只会打印 1 2 3 4 然后就跳出轮回了
    end
end
-- 调试
function foo(...)
    do
        return 
    end
    print("实行 foo 函数") -- 不会打印
end
foo(1, 2 ,3)

5. 函数

  1. 函数是对语句和表达式举行笼统的主要机制

函数的两种用法

  1. 一是能够完成特定的使命,一句函数挪用被视为一条语句
  2. 二是只用来盘算并返回特定结果,视为一句表达式
print("hello") -- 用来完成打印使命,视为一条语句
a = os.date() -- os.date() 用来返回日期,视为一句表达式

两种用法的共同点

  1. 都须要将一切参数放到一对圆括号中 ()
  2. 但当参数为字面字符串或 table 构造式的时刻 ()能够省略
  3. 纵然挪用函数没有参数,也必需要有一对空的圆括号 ()
print "hello" -- hello
print {1, 2, 3} -- 1 2 3
print(os.date) -- 当前日期

定义

  1. function 是建立函数的关键字
  2. function add add 是函数的称号
  3. function add(n) n 是函数的形式参数,简称为形参
  4. add(4) 4 是挪用 add()函数时的现实参 ,简称为实参
  5. 实参过剩形参,过剩的实参被「扬弃」
  6. 形参过剩实参,过剩的形参被置为nil
function foo(a, b)
    return a or b
end
foo(1) -- a = 1, b = nil
foo(1, 2) -- a = 1, b = 2
foo(1, 2, 31) -- a = 1, b = 2, 过剩的 31 被扬弃
-- 面向对象式挪用
o.foo(o, x)
o:foo(x) -- 与上面的结果一样,: 冒号操纵符,隐式的将 o 作为第一个参数

多重返回值

  1. lua 中的函数许可返回多个结果
  2. 用逗号分开所须要返回的一切参数
string.find("you are cool", "are") -- 5 7 返回找到的字符串的开头位置和末端位置
-- 查找数组中的最大元素,并返回这个元素的所在位置
function maximum(a)
    local val = 1
    local max = a[val]
    for i,v in ipairs(a) do
        if max < a[i] then
            max = a[i]
            val = i
        end
    end
    return max, val
end
a = {1, 2, 55, 22, 29, 4}
maximum(a)

差别状况下的返回值

  1. 假如将函数作为零丁的语句实行,lua 会抛弃一切的返回值
  2. 假如将函数作为表达式的一部份挪用,只保存函数的第一个返回值
  3. 只要当函数是一系列表达式中的末了一个元素(或只要一个元素的时刻),才会猎取一切的返回值

一系列表达式的4种状况

多重赋值
  1. 假如一个函数挪用是末了(或唯一)的一个表达式,lua 会保存只管多的返回值,用来婚配赋值的变量
  2. 假如一个函数没有返回值或没有返回足够多的返回值,那末 lua 会用 nil 来补充缺失的值
  3. 假如一个函数挪用不是一系列表达式中的末了一个元素,就只能返回一个值
function foo() end
function foo1() return "a" end
function foo2() return "a", "b" end

-- 第一种状况,末了(或唯一)的一个表达式
x, y = foo1() -- x = a, y = b
-- 第二种状况,没有返回值
x = foo() -- nil
-- 第二种状况,没有返回足够多的返回值
x, y, z = foo1() -- x = a, y = b, z = nil
-- 第三种状况,不是表达式中的末了一个元素
x, y = foo2(), 10 -- x = a, y = 10
函数挪用时传入的实参列表
  1. 假如一个函数挪用作为另一个函数挪用的末了一个(或唯一的)实参的时刻,第一个函数的一切返回值都邑作为实参通报给另一个函数
function foo() end
function foo1() return "a" end
function foo2() return "a", "b" end
-- 第四种状况,作为 print 函数中的末了一个(或唯一的)实参
print(foo()) -- nil
print(foo1()) -- "a"
print(foo2()) -- "a" "b"
print(foo1() .. "test") -- "atest"
print(foo2() .. "test") -- "atest"
table 构造式
  1. table 构造式会完全吸收一个函数挪用的一切结果,即不会由任何数目方面的调解
  2. 但这类行动,只要当一个函数挪用作为末了一个元素时才发作
  3. 其他位置上的函数挪用老是只发生一个结果值
function foo() end
function foo1() return "a" end
function foo2() return "a", "b" end
-- 函数挪用是 table 中的末了一个元素
a = {foo2()} -- a = {"a", "b"}
a = {foo2(), 10} -- a = {"a", 10}
return 语句
  1. 将函数挪用放入一对圆括号 () 中,使其只返回一个结果
  2. return 语句背面的内容不须要 () 圆括号
  3. 假如强行加上则会使一个多返回值的函数,强迫其只返回一个 return(f())
function foo0() end
function foo1() return "a" end
function foo2() return "a", "b" end
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)) -- 无返回值,在交互形式中会是一个空行

-- () 包裹
print((foo(1)) -- a
print((foo(2)) -- a
print((foo(0)) -- nil ,应该是强迫返回了一个未初始化的值,由于 foo0() 没有返回值

unpack 函数

  1. 吸收一个数组作为参数
  2. 并从下标 1 入手下手返回该数组的一切元素
  3. 这个预定义函数由 C 言语编写
print(unpack{10, 20, 30}) -- 10 20 30
a, b = unpack{10, 20, 30}  -- a = 10, b = 20
  1. 用于泛型挪用
  2. 泛型挪用就是能够以任何实参来挪用任何函数
-- 挪用恣意函数 f, 而一切的参数都在数组 a 中
-- unpack 将返回 a 中的一切值,这些值作为 f 的实参
f(unpack(a)) 
f = string.find
a = {"hello", "ll"}
f(unpack(a)) -- 3 4 等效于 string.find("hello", "ll")

用 lua 递归完成 unpack

function unpack(t, i)
    i = i or 1
    if t[i] then
        return t[i], unpack(t, i + 1)
    end
end

变长参数

  1. lua 中的函数能够吸收差别数目的实参
  2. 当这个函数被挪用时,它的一切参数都邑被网络到一同
  3. 这部份网络起来的实参称为这个函数的「变长参数」
  4. ... 三个点示意该函数吸收差别数目的实参
  5. 一个函数要接见它的变长参数时,须要用 ... 三个点,此时 ... 三个点是作为一个表达式运用的
  6. 表达式 ... 三个点的行动相似一个具有多重返回值的函数,它返回的是当前函数的一切变长参数
  7. 具有变长参数的函数也能够具有恣意数目的牢固参数
  8. 但牢固参数肯定要在变长参数之前
  9. 当变长参数中包括 nil ,则须要用 select 接见变长参数
  10. 挪用 select 时,必需传入一个牢固参数 selector (选择开关) 和一系列变长参数
  11. 假如 selector 为数字 n ,那末 select 返回它的第 n 个可变实参
  12. 不然,select 只能为字符串 "#" ,如许 select 会返回变长参数的总数,包括 nil
-- 返回一切参数的和
function add(...)
    local s = 0
    for i, v in ipairs{...} do -- 表达式{...}示意一个由变长参数构成的数组
        s = s + v
    end
    return s
end
print(add(3, 4, 5, 100)) -- 115

-- 调试技能 ,相似与直接挪用函数 foo ,但在挪用 foo 前先挪用 print 打印其一切的实参
function foo1(...)
    print("calling foo:", ...)
    return foo(...)
end


-- 猎取函数的实参列表
function foo(a, b, c) end
function foo(...)
        local a, b, c = ...
end
-- 格式化文本 string.format ,输出文本 io.write
-- 牢固参数肯定要在变长参数之前
function fwrite(fmt, ...)
    return io.write(string.format(fmt, ...))
end
fwrite() -- fmt = nil
fwrite("a") -- fmt = a 
fwrite("%d%d", 4, 5) -- fmt = "%d%d" , 变长参数  = 4, 5

for i = 1, select('#', ...) do
    local arg = select('#', ...)
    <轮回体>
end

签字参数

  1. lua 中的参数通报机制是具有 「位置性」的
  2. 就是说在挪用一个函数时,实参是经由历程它在参数表中的位置与形参婚配起来的
  3. 第一个实参的值与第一个形参相婚配,依此类推
  4. 定义:经由历程称号来指定实参
  5. 可将一切的实参构造到一个 table 中,并将这个 table 作为唯一的实参传给函数
  6. lua 中特别的函数挪用语法,当实参只要一个 table 构造式时,函数挪用中的圆括号 () 是无足轻重的
os.rename  -- 文件更名,愿望到达的结果 os.rename(old = "temp.lua", new = "temp1.lua")
-- lua 不支撑解释的写法
rename = {old = "temp.lua", new = "temp1.lua"}
function rename (arg)
    return os.rename(arg.old, arg.new)
end

x = Window{x = 0, y = 0, width = 300, height = 200, title = "Lua", background = "blue", border = "true"}

-- Window 函数依据请求搜检必填参数,或为某些函数增加默认值
-- 假定 _Window 是真正用于建立新窗口的函数,请求一切参数以准确序次传入
function Window(options)
    if type(options.title) ~= "string" then
        error("no title")
    elseif type(options.width) ~= "number" then
        error("no width")
    elseif type(options.height) ~= "height" 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 -- 默认值为 false(nil)
    )
end
    

由于,现在只学到第五章函数篇,所以只要前五章的温习汇总,很基本,也很主要,也祝贺人人能够脚踏实地地打好地基。

参与评论