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. 字符串加法
    (1) str1 .. str2 (2)字符串和数相加

  2. 数字转字符串
    (1)local a = 10
    a = "" .. a

    (2) tostring(number)
    字符串转数字
    tonumber(string)

  3. 字符串接口:
    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机制要正常运行,需要两点:

  1. 定义的函数必须使用:才会有隐式的传递self机制
  2. 调用的时候也要使用:

元表

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();

面向对象的基本步骤:

  1. 定义一个类的表
  2. 定义一个实例的表
  3. 为这个实例的表加一个元素,并且元表__index指向这个类的表
  4. 利用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是为了正确地将当前实例传递给父类方法,使得父类方法能够访问当前实例的成员。

posted @ 2025-08-02 12:10  木土无心  阅读(14)  评论(0)    收藏  举报