Lua基础
lua的索引从1开始
table初始化
local list = {
[0]= 1, --整数做为索引
helloworld = 3, --字符串作为索引
["0"] = 4
}
print(list[0])
print(list["0"])
print(list["helloworld"])
print(list.helloworld)
字符串操作
-
字符串加法
(1) str1 .. str2 (2)字符串和数相加 -
数字转字符串
(1)local a = 10
a = "" .. a(2) tostring(number)
字符串转数字
tonumber(string) -
字符串接口:
string.len() 字符串的字节数
string.req(s,n) 返回重复n次字符串s的字符串
string.lower(s) 将大写全部转成小写
string.upper(s) 将小写全部转成大写
string.sub(s,i,j) 从第i个到第j个之间的字符串,和其他的不一样,索引从1开始
string.format() 和C语言printf一样,格式化输出数据
string.find 子串查找函数
string.gsub 字符串替换函数
例子:
string.gsub("helloworld","ll","ww") --全部替换
string.gsub("hellllloworld","ll","ww",1) --替换一次
table
lua的表有两部分
一部分是数组,一部分是key value
local tab = {}
tab[1] = 1
tab[2] = 2
tab[3] = 3
tab[4] = 4
tab[5] = 5
tab[11] = 0
遍历数组
for i = 1,#tab do
print(tab[i])
end
输出 1, 2, 3, 4, 5
for k,v ipairs (tab) do
print(k,v)
end
输出 1, 2, 3, 4, 5
遍历所有元素
for k,v in pairs (tab) do
print(k,v)
end
输出 1, 2, 3, 4, 5, 0
unpack 多返回值函数
local array = {1,2,3,4,5,6}
local _,_,_,lhs,rhs = unpack(array)
print(lhs,rhs)
--输出4,5
require
require(“lua文件名”)
require "lua 文件名"
会将这个lua文件执行一次
如果多次require,也只会装载一次(执行一次)
如果这个文件最后有一个return XX
那么require这个文件最后会得到这个XX
默认情况下lua代码编写的函数是不能被外部识别的
在某个lua文件最上方标记 module(包名,package.seeall)
在这个lua文件标记上这个之后,在另外一个lua文件里面只需要require一次,那么所有的lua文件里面都可以用这个标记的lua文件中的方法
lua中的点号和冒号
冒号定义的函数,多一个机制,self
举例:
local a = {}
function a.test()
print("a.test")
end
a.test()
这里定义了一个表a,他有个元素是test函数
但是这个函数里面没有self,需要显式的加上,这里的self就是a本身
function a.test(self)
print("a.test",self)
end
冒号则直接将self绑定进了函数内部
local b = {}
function b:test()
print("b:test",self)
end
b:test()
这里self打出来是b
但是如果是
b.test()
这里的self是nil
function b.test2()
print("b.test",self)
end
b.test2()
这里的self打出来是nil
self机制要正常运行,需要两点:
- 定义的函数必须使用:才会有隐式的传递self机制
- 调用的时候也要使用:
元表
local a = {}
local meta_a = {
__index = {
name = "rose",
age = 33,
sex = 0,
}
}
--设置表的元表
setmetatable(a,meta_a)
--获取表的元表
getmetatable(a)
这两个表相加,第一个参数是一个表,第二个参数也是一个表
meta_a叫做a的元表
元表里面有个非常重要的key:__index
特点:
当我们搜索一个表的key的时候,如果在当前的表里没有搜索到这个key
lua解释器会到我们这个表的元表里面的__index里找这个key
一定是优先在自己的表里面查找这个key
例如
print(a.name)
这里输出rose
面向对象
lua没有面向对象的语法,但是可以模拟
local base = {}
function base:test()
print("base:test",self)
end
function base:new(instance)
if not instance then
instance = {}
end
--将base自己作为元表里的index元素,设置为instance的元表,这里调用instance里面的函数,都可以直接去base里面查找
setmetatable(instance,{__index = self})
return instance
end
local b = base:new();
b:test();
面向对象的基本步骤:
- 定义一个类的表
- 定义一个实例的表
- 为这个实例的表加一个元素,并且元表__index指向这个类的表
- 利用self机制,表的实例:表的函数时,隐式的帮我们传递了实例的表为self到函数里。
继承
基类:
local person = {}
function person:test()
print("person:test",self)
end
function person:get_age()
print("person:get_age")
end
function person:new(instance)
if not instance then
instance = {}
end
setmetatable(instance,{__index = self})
return instance
end
子类:
local man= person:new()
function man:test_man()
print("man:test_man")
end
调用:
local p = man:new()
--这里调用new,因为man里面没有这个方法,因此要去__index里面查找,因为是man调用的,所以__index里面传入的self是man自己
p:test_man()
--调用元表里面man的方法
p:test()
--现在P里面查找,再去man里面查找,如果还是没有,就去元表里的元表里面依次查询,在person里找到
重载
function man:get_age()
print("man:get_age")
end
p:get_age()
这里因为man实现了get_age,所以不会再往下查找person的get_age
子类调用父类的函数
用点操作符,显式传入self
function man:get_age()
print("man:get_age")
person.get_age(self)
end
在子类中调用父类方法时,必须显式传入self,因为:
• 我们需要使用点号调用父类方法(避免冒号调用自动传入父类表作为self)。
• 我们需要确保父类方法操作的是当前子类实例的数据。
• 这样才符合面向对象中多态的特性,即父类方法可以操作子类实例。
因此,传入self是为了正确地将当前实例传递给父类方法,使得父类方法能够访问当前实例的成员。
浙公网安备 33010602011771号