第六日笔记

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. and And 不同,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

因为,目前只学到第五章函数篇,所以只有前五章的复习汇总,很基础,也很重要,也祝愿大家可以踏踏实实地打好地基。

lua学习之复习汇总篇的更多相关文章

  1. lua学习之基础概念篇

    基础概念 程序块 (chunk) 定义 lua 中的每一个源代码文件或在交互模式(Cmd)中输入的一行代码都称之为程序块 一个程序块就是一连串语句或者命令 lua 中连续的语句不需要分隔符,但为了可读 ...

  2. c++的学习内容一汇总篇(常更新)

    在这里假定读者们是有一定编程经验的.例如c#,java,c或者其他任何编程语言. 所有语言都无外乎掌握它的语法,熟悉它的一些库的调用. ---------------语法篇-------------- ...

  3. Lua学习高级篇

    Lua学习高级篇 之前已经说了很多,我目前的观点还是那样,在嵌入式脚本中,Lua是最优秀.最高效的,如果您有不同的观点,欢迎指正并讨论,切勿吐槽.这个系列完全来自于<Programming in ...

  4. lua学习之类型与值篇

    类型与值 lua 是动态类型的语言 在语言中没有类型定义的语法 每个值都携带有它的类型信息 8种基础类型 用 type 可以返回这个值的类型的名称 将一个变量用于不同类型,通常会导致混乱的代码 但合理 ...

  5. VC++/MFC(VC6)开发技术精品学习资料下载汇总

    工欲善其事,必先利其器,VC开发MFC Windows程序,Visual C++或Visual Studio是必须的,恩,这里都给你总结好了,拿去吧:VC/MFC开发必备Visual C++.Visu ...

  6. 【转】自学成才秘籍!机器学习&深度学习经典资料汇总

      小编都深深的震惊了,到底是谁那么好整理了那么多干货性的书籍.小编对此人表示崇高的敬意,小编不是文章的生产者,只是文章的搬运工. <Brief History of Machine Learn ...

  7. Dynamic CRM 2015学习笔记 系列汇总

    这里列出所有 Dynamic CRM 2015学习笔记 系列文章,方便大家查阅.有任何建议.意见.需要,欢迎大家提交评论一起讨论. 本文原文地址:Dynamic CRM 2015学习笔记 系列汇总 一 ...

  8. 机器学习&深度学习经典资料汇总,data.gov.uk大量公开数据

    <Brief History of Machine Learning> 介绍:这是一篇介绍机器学习历史的文章,介绍很全面,从感知机.神经网络.决策树.SVM.Adaboost到随机森林.D ...

  9. Lua学习笔记6:C++和Lua的相互调用

        曾经一直用C++写代码.话说近期刚换工作.项目组中的是cocos2dx-lua,各种被虐的非常慘啊有木有.     新建cocos2dx-lua项目.打开class能够发现,事实上就是C++项 ...

随机推荐

  1. 2017CCPC杭州(ABCDJ)

    所有的题目在这里<--- 待补... Problem A. HDU6264:Super-palindrome 题意: 题目定义了一个超级回文串,这个串满足:它的任一奇数长度的串都是回文串. 现在 ...

  2. 假设检验的Python实现

    结合假设检验的理论知识,本文使用Python对实际数据进行假设检验. 导入测试数据 从线上下载测试数据文件,数据链接:https://pan.baidu.com/s/1t4SKF6U2yyjT365F ...

  3. 《C++Primer》第五版习题答案--第二章【学习笔记】

    C++Primer第五版习题解答---第二章 ps:答案是个人在学习过程中书写,可能存在错漏之处,仅作参考. 作者:cosefy Date: 2020/1/9 第二章:变量和基本类型 练习2.1: 类 ...

  4. SpringBoot+Neo4j在社交电商中,讲述你是怎么被绑定为下线的

    上两篇文章我们主要讲解了Neo4j的基本知识以及Neo4j的基本使用,这篇文章我们就以实例来深入的理解一下,我们以社交电商中的绑定关系为例,使用SpringBoot+Neo4j来实现. Neo4j文章 ...

  5. vue 项目使用JSbrideg.js与app通信

    一.建立JSbrideg.js文件 var jsBridge = {     isAndroid: null,     isIOS: null,     callHandlerFunc: functi ...

  6. hadoop各版本hadoop.dll和winutils.exe缺少这两个文件

    1.1 缺少winutils.exeCould not locate executable null \bin\winutils.exe in the hadoop binaries1.2 缺少had ...

  7. C++读书笔记

    C与C++的不同点 C++在struct,union中定义的函数叫成员函数,在class中定义的数据叫数据成员 C++引入了三个存取权限的关键字:public,protected,private pu ...

  8. TensorFlow or PyTorch

    既然你已经读到了这篇文章,我就断定你已经开始了你的深度学习之旅了,并且对人造神经网络的研究已经有一段时间了:或者也许你正打算开始你的学习之旅.无论是哪一种情况,你都是因为发现你陷入了困惑中,才找到了这 ...

  9. 2.Java程序运行机制

    1.编译型:compile,把所有东西翻译好,若有更新需要重新全部翻译.执行速度够快,对操作系统要求比较低.开发操作系统时用到编译型语言,例如c/c++...运行时需编译整个程序 2.解释性:运行一个 ...

  10. JSON解析值富文本

    解析前端传递的JSON数据中可能如下 { "result": "<input value="Test" type="button&qu ...