【系列】潜水党的简单lua教程二
上次讲到了变量的使用规则。
这次就先讲一个lua里面会频繁使用到的东西:table(表)
table是lua的一种数据结构,可以用来储存数据,且table不固定大小,可以根据需要来扩容table里的内容。
那么如何使用table呢?请看耐心看完下面的内容。
当你想要定义一个新表的时:
例:
my = {} -- 创建表
当你想要让它储存数据时:
例:
my[1] = ‘王大锤’
print(my[1]) -- 输出结果:王大锤
这里是不是跟ydwe里的全局变量很相似呢?
对没错,但又有一定的区别。
表在存储数据的时候,是会有一个索引的。
而这个索引可以是任何值,这与编辑器的全局变量的索引是截然不同的。
当你想要移除数据时:
my[1] = nil
-- 回收且释放数据
以上是table的一些简单操作,更进阶一点的用法就是,了解lua里面,专门为table提供的一些函数。
table.insert(table,[index],key):
为指定table添加key,如果存在index,那么会在索引为index的位置上添加key。
table.remove(table,[index]):
为指定table移除key,如果不存在index,则移除在table末尾的key,即index初始长度为table的长度;
如果存在index,那么会移除索引为index的key,并且排序在index其后的key全部向前移动;
insert以及remove基本上是用到最多的两个函数。
另外还存在有sort以及concat两个函数,前者作为table的排序,后者连接table内的值,基本用不到,这里不做多解释。
另外还有一些常用的方法,如遍历table内的数据,获取table长度等等。
例:
my = {
1, -- 数据结尾需要加上,
2, -- 否则会报错
3, -- 末尾数据可加可不加
}
遍历table内数据:
for k,v in pairs (my) do
-- 其中 k 是数据的索引, v才是数据本身
print(k, v)
end
获取table的长度:
例1:
local num = 0
for k,v in pairs (my) do
num = num + 1
end
print('my的长度为',num) -- 输出结果:my的长度为3
例2:
local num = #my
print('my的长度为',num) -- 输出结果:my的长度为3
以上就是遍历table数据以及获取长度的方法。
除此之外,table还可以用来做模块、包、对象等等,不过你只做图的话,用不到这些。
这里简单的讲一下模块的做法,与函数有关。
新建一个lua脚本,命名为abc.lua
my = {} -- 创建一个新模块
my[1] = 123 -- 为模块添加一个数据
-- 为模块添加一个函数
function my.init()
print(my[1])
end
-- 返回模块
return my
新建另一个脚本,命名为cba.lua
local my = require 'abc'
my.init() -- 调用模块内的函数
-- 输出my[1]的内容
一般来说你只是作图的话用不到这个,常规的做法是定义一个table,然后将函数、常量等等存进table,直接调用table就可以直接使用了。
完全不需要多此一举专门写个模块。
写模块的好处是可以被你写的局部变量获取到,你调用起来更自由。
table的基础用法已经讲完了,接下来就是函数的定义。
jass的函数定义:
function init takes nothing returns nothing
endfunction
lua的函数定义:
function init()
end
两者相对比较,你会发现lua的写法更加简洁。
那么lua应该怎么为函数添加参数呢?
例:
function init(a)
print(a)
end
init(123) -- 输出结果:123
那如果函数的参数有十几二十多个呢?一个个写岂不是要累死?
lua提供了一种可变参数的写法。
例:
-- 固定参数
function init(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y ,z)
print(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y ,z)
end
-- 可变参数
function init(...)
for k, v, in ipairs {...} do
print(k, v) -- 这里的k是参数索引,v是参数值
end
end
这两种写法,得到的数据基本没有区别,并且第二种可变参数的写法,你可以根据需求去扩展参数。
同时,可变参数同样也可以与固定参数共存,如以下写法。
例:
function init(a, b, c, ...)
local list = {...} -- 可变参数列表
for k, v, in ipairs {...} do
print(k, v) -- 这里的k是参数索引,v是参数值
end
print(a, b, c)
end
但固定参数的位置需要在可变参数之前。
如果可变参数项里存在nil呢?那会不会报错呢?
这里可以用select('#', ...) 来获取可变参数的长度,如果把'#'换成任意数n,那么就会从n的位置开始,获取剩下参数项的长度。
接下来是函数的调用。
jass:
function init takes nothing returns nothing
endfunction
// 调用
call init()
lua:
function init()
end
-- 调用
init()
lua不需要加上call的前缀,可以直接填写函数名调用。
但这样写就是一个全局函数,如果地图长期更新,函数越来越多,会让你很难记住每个函数的大致作用是什么。
所以就需要结合之前提到的table来使用。
往table里存函数的方法并不止一种。
my = {} -- 创建一个表
例1:
-- 存一个函数
function my.init()
end
例2:
-- 存一个函数
function my:init()
end
这里与例1的区别在于,例1用到的是点,例2用到的是冒号。
两者的区别在于,冒号会多一个self的参数,self代表的是这个函数本身。
当然例1也可以做到例2的效果,如:
function my.init(self)
end
通过这里可以看得出来,冒号的作用仅仅只是省略了一个self的参数填写过程。
还有一种存函数的方法,如:
-- 等同于例2
my = {
init = function(self)
end
}
还有一点需要说明的是,lua支持局部函数,与局部变量性质一样,只能在当前脚本内使用。
局部函数的写法:
例1:
local function init()
end
例2:
local init = function()
end
其他的下次在写,码字码累了。