前情提要
Lua 通过一个虚拟栈与 C 的交互,正数索引自底向上取值,负数索引自顶向下取值。
Lua 中的 Table(表)结构可以使用任何数据作为 key 进行取值。使用 C API 访问 Table 中的元素有两种方法:
lua_getglobal(L, t);
lua_pushinteger(L, k); -- 这里可以换成其它类型的 lua_pushXXXX(L, k) 压数据到栈顶作key
lua_gettable(L, -2);
lua_getglobal(L, t);
lua_getfield(L, -1, k);
在结束时,栈上的情况均为:栈顶为 t[k]
,次顶元素为 Table 类型的 t
。第二种方法其实是第一种方法在「key 为字符串」时的特殊写法。
C API 遍历 Table
lua_getglobal(L, t);
lua_pushnil(L);
while (lua_next(L, -2)) {
/* 此时栈上 -1 处为 value, -2 处为 key */
lua_pop(L, 1);
}
lua_next
函数针对 -2 处(参数指定)的 Table 进行遍历。弹出 -1 处(栈顶)的值作为上一个 key(为 nil 时视为请求首个 key),压入 Table 中的下一个 key 和 value。返回值表示是否存在下一个 key。
另外在循环中处理值时要记得随时清理栈,否则 Table 就不在 -2 了。(也可以考虑在 lua_getglobal
后用 lua_gettop
存下 Table 的正数索引。)
虽然这是手册中记载的遍历方法,但这种方法在遍历时并没有一定的遍历顺序,于是便又有了下面的方法。
用整数 Key 进行并不那么完美的遍历
lua_getglobal(L, t);
len = lua_objlen(L, -1);
for (i = 1; i <= len; i++) {
lua_pushinteger(L, i);
lua_gettable(L, -2);
/* 此时栈顶即为 t[i] 元素 */
lua_pop(L, 1);
}
这种方法无视了非整数 key,但可以保证遍历顺序。如果只关注整数 key,可以考虑用这种遍历方法 :)
Lua 本身是个很简练的语言,作为语言,变量似乎是比不可缺的一员。
Lua 中的变量没有类型,只管赋值即可。比如在 Lua 命令行下输入:
end_of_world = "death"
print(end_of_world)
end_of_world = 2012
print(end_of_world)
上面这四行代码 Lua 不会报错,而会输出:
death
2012
虽说变量没有类型,但并不是说数据不分类型。Lua 基本数据类型共有八个:nil
、boolean
、number
、string
、function
、userdata
、thread
、table
。
nil
就是 C/C++ 中的 NULL
,表示没有有效值。所有未定义的变量都是 nil
。
- Number 即实数,Lua 中的所有数都用双精度浮点数表示。
- Table 是很强大的数据结构,也是 Lua 中唯一的数据结构。可以看作是数组或者字典。
- Function / Userdata / Thread 目前还不是很了解 =。=
可以用 type
函数取得表达式的数据类型:
print(type(undefined_var))
print(type(true))
print(type(3.14))
print(type('Hello World'))
print(type(type))
print(type({}))
Lua 各种操作符和其它语言都是差不多的,只是有几个特殊的比较不一样,比如:
a ~= b
即 a
不等于 b
a ^ b
即 a
的 b
次方
a .. b
将 a
和 b
作为字符串连接
逻辑运算符直接就是英语的 and
or
not
三个单词。
另外 Lua 还支持多重赋值。也就是说:等号右边的值依次赋值给等号左边的变量。比如:
year, month, date = 2011, 3, 12
print(year, month, date)
于是,交换两个变量值的操作也变得非常简单:
a, b = b, a
最后,变量有局部和全局之分。加 local
修饰符的都是局部变量,否则就是全局变量。
p.s. 要从 Lua 命令行中退出,可以输入 os.exit()
或者直接 Ctrl-C
。
其实本来用过一点点 Lua,不过都是需要什么功能就慢慢找 Reference Manual,这回毕业设计终于要用 Lua 写完整的东西了,于是准备把 PIL 慢慢看一遍。
首先是最简单的 Lua 为 C/C++ 程序变量赋值,类似史前的 INI 配置文件。
width = 640
height = 480
这样的赋值即设置全局变量,本质上就是在全局表中添加字段。
阅读剩余部分...
- «
- 1
- 2