10.表

10.表


10.1 知识点

基本概念

  • 表是一切复杂数据的基础,包括数组、二维数组、字典、类和结构体等等。
  • 所有的复杂类型都是表。
  • 表还提供了一些公共方法给我们使用

一维数组

一维数组声明

  • 一维数组声明语法:表变量 = { 元素1, 元素2, …, 元素n }
  • 表的元素可以是任意类型
a = { 1, 2, 3, "4", nil, "6", true, nil }

获得一维数组中的元素

  • 获得一维数组中的元素语法:表变量[索引]
  • Lua中的表的索引默认从1开始
print(a[0]) -- nil
print(a[1]) -- 1
print(a[2]) -- 2
print(a[3]) -- 3
print(a[4]) -- 4
print(a[5]) -- nil
print(a[6]) -- "6"
print(a[7]) -- true
print(a[8]) -- nil

获取一维数组的长度

  • 获取一维数组的长度语法:#表变量
  • ‘#’ 是通用的获取数组长度的关键字
  • 如果数组中的某个元素为 nil,它会影响 ‘#’ 操作符返回的数组长度
  • 在计算长度时,nil 元素会被忽略
  • 获取一维数组的长度时,只要遍历到数组元素是 nil,就会认为遍历结束并返回长度
  • 但是由于 Lua 的底层实现和版本差异,有时可能需要遇到第二个 nil 元素才会认为遍历结束并返回长度
  • 因此,不必过于依赖 ‘#’ 操作符返回的值,只需要注意当数组元素存在不确定性时,’#’ 操作符获取的一维数组长度可能不准确
a = { 1, 2, 3, "4", nil, "6", true, nil }
print(#a) -- 7(Lua 底层实现可能导致遇到第二个 nil 才返回一维数组长度)
a = { 1, nil, 3, "4", nil }
print(#a) -- 1(遇到第一个 nil 就返回)
a = { 1, 2, nil, 4, "5", true, nil }
print(#a) -- 2(遇到第一个 nil 就返回)

遍历一维数组

-- 使用for循环遍历 #表变量获得表长的问题会存在 不赘述
a = { 1, 2, 3, "4", nil, "6", true, nil }
for i = 1, #a do
    print(a[i])
end

二维数组

二维数组声明

-- 二维数组声明语法:
-- 表变量 = 
-- {
--  { 表1元素1,表1元素2, 表1元素1 }, 
--  { 表2元素1,表2元素2, 表2元素1 } ,
--   ..., 
--  { 表n元素1,表n元素2, 表n元素1 }  
-- }
a = { { 1, 2, 3 },
    { 4, 5, 6 } }

获得二维数组中的元素

-- 获得二维数组中的元素语法:表变量[索引1][索引2]
print(a[1][1]) -- 1
print(a[1][2]) -- 2
print(a[1][3]) -- 3
print(a[2][1]) -- 4
print(a[2][2]) -- 5
print(a[2][3]) -- 6

遍历二维数组

-- 使用两次for循环遍历 #表变量获得表长的问题会存在 不赘述
for i = 1, #a do
    b = a[i]
    for j = 1, #b do
        print(b[j])
    end
end

自定义索引

  • 表自定义索引声明语法:表变量 = { [索引1] = 元素1, [索引2] = 元素2, …, [索引n] =元素n }
  • 表自定义索引规则:指定索引的元素关联指定索引,未指定索引的元素的索引从1按顺序增加
  • 注意:
  • 重复索引会报错 比如按顺序增加已经存在了索引2 在指定索引[2] = 某元素会报错
  • 同时#表变量返回表长也可能不准确 不要相信#表变量得到的表长
a = { [0] = 1, 2, 3, [-1] = 4, 5 }
print(#a)    -- 3 只把2,3,5元素算入表长
print(a[0])  -- 1
print(a[1])  -- 2
print(a[2])  -- 3
print(a[-1]) -- 4
print(a[3])  -- 5
-- 虽然5和3中间夹了个-1索引 但是还是被当做上一个没有被自定义索引按顺序的下一个索引
-- 比如上一个没有自定义索引的元素3是索引2 所以5是索引3
print(a[4]) -- nil 没有索引4的元素

a = { [1] = 1, [2] = 2, [4] = 4, [5] = 5, }
print(#a)       -- 5 2和4中间只隔了一个nil 导致5个元素都能被算入表长
for i = 1, #a do
    print(a[i]) -- 1 2 nil 4 5
end

a = { [1] = 1, [2] = 2, [5] = 4, [6] = 6, }
print(#a)       -- 2 2和5中间只隔了两个nil 只有1,2被算入表长
for i = 1, #a do
    print(a[i]) -- 1 2
end

迭代器遍历

  • #表变量得到表长并不准确
  • 所以一般不要用#来遍历表
  • 建议遍历表时使用迭代器遍历

ipairs遍历

  • ipairs遍历可以遍历键值对,也可以只遍历键不遍历值
  • ipairs遍历还是从索引1开始往后遍历的 小于等于索引0的元素是得不到的
  • ipairs遍历只能找到连续索引的 索引如果中间断序了,也无法遍历出后面的内容
  • 比如如下遍历找不到5索引所在的元素6,因为没有4元素
  • 可以看出仍然没有解决#表变量带来的问题

a = { [0] = 1, 2, [-1] = 3, 4, 5, [5] = 6 }
--ipairs迭代器遍历键值对
--ipairs遍历键值对语法:
-- for 键变量,值变量 in ipairs(表变量) do
-- 循环体
-- end
for i, k in ipairs(a) do
    print("ipairs遍历键值对" .. i .. "_" .. k)
    -- ipairs遍历键值对1_2
    -- ipairs遍历键值对2_4
    -- ipairs遍历键值对3_5
end
--ipairs迭代器遍历键
--ipairs遍历键值对语法:
-- for 键变量 in ipairs(表变量) do
-- 循环体
-- end
for i in ipairs(a) do
    print("ipairs遍历键" .. i)
    -- ipairs遍历键1
    -- ipairs遍历键2
    -- ipairs遍历键3
end

pairs遍历

  • pairs遍历可以遍历键值对,也可以只遍历键不遍历值
  • pairs遍历能够把所有的键都找到 可以得到所有键值对
  • 解决#表变量带来的问题
a = { [0] = 1, 2, [-1] = 3, 4, 5, [5] = 6 }
--pairs遍历键值对语法:
-- for 键变量,值变量 in pairs(表变量) do
-- 循环体
-- end
--pairs能够把所有的键都找到 这样就可以得到所有键值对
for i, v in pairs(a) do
    print("pairs遍历键值对" .. i .. "_" .. v)
    -- pairs遍历键值对1_2
    -- pairs遍历键值对2_4
    -- pairs遍历键值对3_5
    -- pairs遍历键值对0_1
    -- pairs遍历键值对-1_3
    -- pairs遍历键值对5_6
end
--pairs遍历键值对语法:
-- for 键变量 in ipairs(表变量) do
-- 循环体
-- end
for i in pairs(a) do
    print("pairs遍历键" .. i)
    -- pairs遍历键1
    -- pairs遍历键2
    -- pairs遍历键3
    -- pairs遍历键0
    -- pairs遍历键-1
    -- pairs遍历键5
end

字典

字典的声明

--字典的声明语法:表变量 = {["键1"] = "值1", ["键2"] = "值2",...["键3"] = "值3"]}
--字典是由键值对构成  和自定义索引声明类似 只是键和值多了双引号""包裹
a = { ["name"] = "韬哥", ["age"] = 22, ["1"] = 1 }

访问字典值

--表变量["键"] 用中括号来访问值 键要带上双引号"""
print(a["name"]) --韬哥
print(a["age"])  --22
print(a["1"])    --1
--表变量.键 用点访问值 类似C#中.成员变量的形式得到值
print(a.name)    --韬哥
print(a.age)     --22
--虽然可以通过.成员变量的形式得到值 但是不能是数字
-- print(a.1)--报错
print(a["1"]) --1

修改字典值

--表变量["键"] = "新值"
a["name"] = "韬老师";
print(a["name"]) --韬老师
--表变量.键 = "新值"
a.name = "韬老师帅";
print(a.name) --韬老师帅

新增字典值

--表变量["新键"] = "新值"
a["sex"] = false
print(a["sex"]) --false
--表变量.新键 = "新值"
a.handsome = true
print(a.handsome) --true

删除字典值

--表变量["键"] = nil
a["sex"] = nil
print(a["sex"]) --nil
--表变量.键 = nil
a.handsome = nil
print(a.handsome) --nil

字典的遍历

--遍历一定要用pairs迭代器遍历
--键值对遍历
for k, v in pairs(a) do
    --可以传多个参数 一样可以打印出来
    print(k, v)
    -- 1	1
    -- name	韬老师帅
    -- age	22
end
--遍历键 通过键得到值
for k in pairs(a) do
    print(k)
    print(a[k])
    -- 1
    -- 1
    -- name
    -- 韬老师帅
    -- age
    -- 22
end
--遍历值 可以用_省略键
for _, v in pairs(a) do
    print(_, v)
    -- 1	1
    -- name	韬老师帅
    -- age	22
end

类和结构体

  • Lua中是默认没有面向对象的 需要我们自己来实现 Lua中实现类和结构体都是类似的

类声明

-- 类声明语法:
-- 类 = {
--成员变量,
--成员函数,
-- ...
-- }

Student = {
    --年龄
    age = 1,
    --性别
    sex = true,
    --打印函数1
    Print1 = function()
        print("进入打印函数1")

        print(age)
        --这样打印的age和Student类中的age没有任何关系 打印的age是一个全局变量

        --在表内部函数中 调用类本身的属性或者方法 要指定类
        --类.属性 或 类.方法()
        print(Student.age)
        print(Student.sex)

        print("退出打印函数1")
    end,
    --打印函数2
    Print2 = function(myStudent)
        print("进入打印函数2")

        --可以使用有参函数 把当前类作为一个参数传进来函数中来
        --在函数内部调用类本身的属性或者方法 在内部访问
        print(Student.age)
        print(myStudent.sex)

        print("退出打印函数2")
    end
}

实例化类对象

  • C#是使用类实例化new出对象 静态成员.出成员
  • Lua中是没有实例化new的概念的 类的表现更像是一个类中有很多静态成员
  • 只会要自己实现面向对象

得到类的成员变量

--直接 类.变量 得到变量
print(Student.age) --1
print(Student.sex) --true

在类外添加的成员变量

--声明类过后 可以直接在类外 类.变量 = 值 添加成员变量
Student.name = "韬老狮"
print(Student.name) --韬老狮

使用.调用类的成员方法

Student.Print1()
-- 进入打印函数1
-- nil
-- 1
-- true
-- 退出打印函数1
Student.Print2(Student) --传入当前类作为参数
-- 进入打印函数2
-- 1
-- true
-- 退出打印函数2

使用.在类外添加的成员方法

--声明类过后 可以直接在类外
-- 类.方法 = function()
--     函数体
-- end
-- 来添加成员方法
Student.Print3 = function()
    print("进入打印函数3")

    print(Student.age)
    print(Student.sex)

    print("退出打印函数3")
end
Student.Print3()
-- 进入打印函数3
-- 1
-- true
-- 退出打印函数3

使用:调用类的成员方法

--冒号调用方法 会默认把调用者 作为调用的方法的第一个参数传入方法中
Student:Print2() --虽然没有显式的传入Student作为参数 但是因为是:调用函数 已经隐式的传入Student作为参数了
-- 进入打印函数2
-- 1
-- true
-- 退出打印函数2

使用:在类外添加的成员方法 self来表示默认传入的第一个参数

--声明类过后 可以直接在类外
-- 类:方法 = function()
--     函数体
-- end
-- 来添加成员方法
--使用了:声明方法后 代表方法会有一个默认的参数
--在方法内 通过self来表示默认传入的第一个参数
function Student:Print4() --虽然没有显式的有参数 但是因为是:声明函数 已经隐式的让这个函数有参数了
    print("进入打印函数4")

    print(self.age)
    print(self.sex)

    print("退出打印函数4")
end

在类外调用使用:在类外添加的成员方法

-- Student.Print4()--报错 Print4因为是:声明函数 需要传入参数
Student.Print4(Student) --传入了Student类自身作为参数 正常调用
-- 进入打印函数4
-- 1
-- true
-- 退出打印函数4
Student:Print4() --冒号调用方法 会把调用者Student作为第一个参数传进去 正常调用
-- 进入打印函数4
-- 1
-- true
-- 退出打印函数4

表的公共方法

插入 table.insert

t1 = { { age = 1, name = "111" }, { age = 2, name = "222" } }
t2 = { name = "韬老狮", sex = true }
-- table.insert(要插入元素的表,插入的表) 会把插入的表的表作为要插入元素的表作为顺序索引的最后一个元素
print(#t1)        --2
table.insert(t1, t2);
print(#t1)        --3
print(t1[1].name) --111
print(t1[2].name) --222
print(t1[3].name) --韬老狮 代表把t2的的元素插入成功了

删除 table.remove

t1 = { { age = 1, name = "111" }, { age = 2, name = "222" }, { name = "韬老狮", sex = true } }
--table.remove(要移除元素的表) 会移除传入的表的最后一个索引的内容
print(#t1)        --3
table.remove(t1)
print(#t1)        --2
print(t1[1].name) --111
print(t1[2].name) --222
print(t1[3])      --nil 最后一个元素被移除了
--table.remove(要移除元素的表, 移除元素索引)
print(#t1)        --2
table.remove(t1, 1)
print(#t1)        --1
print(t1[1].name) --222 name为111的元素被移除了

排序 table.sort

t1 = { 5, 2, 4, 3, 1 }
--table.sort(要排序的表) 默认升序排列
table.sort(t1)
for _, v in pairs(t1) do
    print(v)
    -- 1
    -- 2
    -- 3
    -- 4
    -- 5
end
--table.sort(要排序的表,排序规则函数)
-- 排序函数接受两个参数,通常命名为 a 和 b,用于表示待比较的两个元素。
-- 排序函数根据 a 和 b 的比较结果返回 true 或 false,以指示元素的相对顺序。
-- 如果排序函数返回 true,则表示 a 应该在 b 前面。
-- 如果排序函数返回 false,则表示 b 应该在 a 前面。
-- 排序函数必须返回布尔值,且只有 true 或 false。
--降序
table.sort(t1, function(a, b)
    return a > b
end)
for _, v in pairs(t1) do
    print(v)
    -- 5
    -- 4
    -- 3
    -- 2
    -- 1
end
--升序
function AscendingSort(a, b)
    return a < b
end

table.sort(t1, AscendingSort)
for _, v in pairs(t1) do
    print(v)
    -- 1
    -- 2
    -- 3
    -- 4
    -- 5
end

拼接 table.concat

t1 = { "123", "456", "789", "10101" }
--table.concat(要拼接的表, "元素间的符号") 返回值是一个拼接好的字符串
str = table.concat(t1, "@@")
print(str) --123@@456@@789@@10101

10.2 知识点代码

print("**********表************")


print("**********知识点一 基本概念************")
-- 表是一切复杂数据的基础,包括数组、二维数组、字典、类和结构体等等。
-- 所有的复杂类型都是表。
-- 表还提供了一些公共方法给我们使用


print("**********知识点二 一维数组************")

-- 一维数组声明语法:表变量 = { 元素1, 元素2, ..., 元素n }
-- 表的元素可以是任意类型
a = { 1, 2, 3, "4", nil, "6", true, nil }

-- 获得一维数组中的元素语法:表变量[索引]
-- Lua中的表的索引默认从1开始
print(a[0]) -- nil
print(a[1]) -- 1
print(a[2]) -- 2
print(a[3]) -- 3
print(a[4]) -- 4
print(a[5]) -- nil
print(a[6]) -- "6"
print(a[7]) -- true
print(a[8]) -- nil

-- 获取一维数组的长度语法:#表变量
-- '#' 是通用的获取数组长度的关键字
-- 如果数组中的某个元素为 nil,它会影响 '#' 操作符返回的数组长度
-- 在计算长度时,nil 元素会被忽略
-- 获取一维数组的长度时,只要遍历到数组元素是 nil,就会认为遍历结束并返回长度
-- 但是由于 Lua 的底层实现和版本差异,有时可能需要遇到第二个 nil 元素才会认为遍历结束并返回长度
-- 因此,不必过于依赖 '#' 操作符返回的值,只需要注意当数组元素存在不确定性时,'#' 操作符获取的一维数组长度可能不准确
a = { 1, 2, 3, "4", nil, "6", true, nil }
print(#a) -- 7(Lua 底层实现可能导致遇到第二个 nil 才返回一维数组长度)
a = { 1, nil, 3, "4", nil }
print(#a) -- 1(遇到第一个 nil 就返回)
a = { 1, 2, nil, 4, "5", true, nil }
print(#a) -- 2(遇到第一个 nil 就返回)

-- 遍历一维数组
-- 使用for循环遍历 #表变量获得表长的问题会存在 不赘述
a = { 1, 2, 3, "4", nil, "6", true, nil }
for i = 1, #a do
    print(a[i])
end


print("**********知识点三 二维数组************")

-- 二维数组声明语法:
-- 表变量 = 
-- {
--  { 表1元素1,表1元素2, 表1元素1 }, 
--  { 表2元素1,表2元素2, 表2元素1 } ,
--   ..., 
--  { 表n元素1,表n元素2, 表n元素1 }  
-- }
a = { { 1, 2, 3 },
    { 4, 5, 6 } }

-- 获得二维数组中的元素语法:表变量[索引1][索引2]
print(a[1][1]) -- 1
print(a[1][2]) -- 2
print(a[1][3]) -- 3
print(a[2][1]) -- 4
print(a[2][2]) -- 5
print(a[2][3]) -- 6

-- 遍历二维数组
-- 使用两次for循环遍历 #表变量获得表长的问题会存在 不赘述
for i = 1, #a do
    b = a[i]
    for j = 1, #b do
        print(b[j])
    end
end


print("**********知识点四 自定义索引************")

--表自定义索引声明语法:表变量 = { [索引1] = 元素1, [索引2] = 元素2, ..., [索引n] =元素n }
--表自定义索引规则:指定索引的元素关联指定索引,未指定索引的元素的索引从1按顺序增加
--注意:
--重复索引会报错 比如按顺序增加已经存在了索引2 在指定索引[2] = 某元素会报错
--同时#表变量返回表长也可能不准确 不要相信#表变量得到的表长

a = { [0] = 1, 2, 3, [-1] = 4, 5 }
print(#a)    -- 3 只把2,3,5元素算入表长
print(a[0])  -- 1
print(a[1])  -- 2
print(a[2])  -- 3
print(a[-1]) -- 4
print(a[3])  -- 5
-- 虽然5和3中间夹了个-1 但是还是被当做上一个没有被自定义索引按顺序的下一个索引
-- 比如上一个没有自定义索引的元素3是索引2 所以5是索引3
print(a[4]) -- nil 没有索引4的元素

a = { [1] = 1, [2] = 2, [4] = 4, [5] = 5, }
print(#a)       -- 5 2和4中间只隔了一个nil 导致5个元素都能被算入表长
for i = 1, #a do
    print(a[i]) -- 1 2 nil 4 5
end

a = { [1] = 1, [2] = 2, [5] = 4, [6] = 6, }
print(#a)       -- 2 2和5中间只隔了两个nil 只有1,2被算入表长
for i = 1, #a do
    print(a[i]) -- 1 2
end


print("**********知识点五 迭代器遍历************")

--#表变量得到表长并不准确
--所以一般不要用#来遍历表
--建议遍历表时使用迭代器遍历

--ipairs遍历
--ipairs遍历可以遍历键值对,也可以只遍历键不遍历值
--ipairs遍历还是从索引1开始往后遍历的 小于等于索引0的元素是得不到的
--ipairs遍历只能找到连续索引的 索引如果中间断序了,也无法遍历出后面的内容
--比如如下遍历找不到5索引所在的元素6,因为没有4元素
--可以看出仍然没有解决#表变量带来的问题
a = { [0] = 1, 2, [-1] = 3, 4, 5, [5] = 6 }
--ipairs迭代器遍历键值对
--ipairs遍历键值对语法:
-- for 键变量,值变量 in ipairs(表变量) do
-- 循环体
-- end
for i, k in ipairs(a) do
    print("ipairs遍历键值对" .. i .. "_" .. k)
    -- ipairs遍历键值对1_2
    -- ipairs遍历键值对2_4
    -- ipairs遍历键值对3_5
end
--ipairs迭代器遍历键
--ipairs遍历键值对语法:
-- for 键变量 in ipairs(表变量) do
-- 循环体
-- end
for i in ipairs(a) do
    print("ipairs遍历键" .. i)
    -- ipairs遍历键1
    -- ipairs遍历键2
    -- ipairs遍历键3
end

--pairs遍历
--pairs遍历可以遍历键值对,也可以只遍历键不遍历值
--pairs遍历能够把所有的键都找到 可以得到所有键值对
--解决#表变量带来的问题
a = { [0] = 1, 2, [-1] = 3, 4, 5, [5] = 6 }
--pairs遍历键值对语法:
-- for 键变量,值变量 in pairs(表变量) do
-- 循环体
-- end
--pairs能够把所有的键都找到 这样就可以得到所有键值对
for i, v in pairs(a) do
    print("pairs遍历键值对" .. i .. "_" .. v)
    -- pairs遍历键值对1_2
    -- pairs遍历键值对2_4
    -- pairs遍历键值对3_5
    -- pairs遍历键值对0_1
    -- pairs遍历键值对-1_3
    -- pairs遍历键值对5_6
end
--pairs遍历键值对语法:
-- for 键变量 in ipairs(表变量) do
-- 循环体
-- end
for i in pairs(a) do
    print("pairs遍历键" .. i)
    -- pairs遍历键1
    -- pairs遍历键2
    -- pairs遍历键3
    -- pairs遍历键0
    -- pairs遍历键-1
    -- pairs遍历键5
end


print("**********知识点六 字典************")

--字典的声明
--字典的声明语法:表变量 = {["键1"] = "值1", ["键2"] = "值2",...["键3"] = "值3"]}
--字典是由键值对构成  和自定义索引声明类似 只是键和值多了双引号""包裹
a = { ["name"] = "韬哥", ["age"] = 22, ["1"] = 1 }

--访问字典值
--表变量["键"] 用中括号来访问值 键要带上双引号"""
print(a["name"]) --韬哥
print(a["age"])  --22
print(a["1"])    --1
--表变量.键 用点访问值 类似C#中.成员变量的形式得到值
print(a.name)    --韬哥
print(a.age)     --22
--虽然可以通过.成员变量的形式得到值 但是不能是数字
-- print(a.1)--报错
print(a["1"]) --1

--修改字典值
--表变量["键"] = "新值"
a["name"] = "韬老师";
print(a["name"]) --韬老师
--表变量.键 = "新值"
a.name = "韬老师帅";
print(a.name) --韬老师帅

--新增字典值
--表变量["新键"] = "新值"
a["sex"] = false
print(a["sex"]) --false
--表变量.新键 = "新值"
a.handsome = true
print(a.handsome) --true

--删除字典值
--表变量["键"] = nil
a["sex"] = nil
print(a["sex"]) --nil
--表变量.键 = nil
a.handsome = nil
print(a.handsome) --nil

--字典的遍历
--遍历一定要用pairs迭代器遍历
--键值对遍历
for k, v in pairs(a) do
    --可以传多个参数 一样可以打印出来
    print(k, v)
    -- 1	1
    -- name	韬老师帅
    -- age	22
end
--遍历键 通过键得到值
for k in pairs(a) do
    print(k)
    print(a[k])
    -- 1
    -- 1
    -- name
    -- 韬老师帅
    -- age
    -- 22
end
--遍历值 可以用_省略键
for _, v in pairs(a) do
    print(_, v)
    -- 1	1
    -- name	韬老师帅
    -- age	22
end


print("**********知识点七 类和结构体************")
--Lua中是默认没有面向对象的 需要我们自己来实现 Lua中实现类和结构体都是类似的

-- 类声明语法:
-- 类 = {
--成员变量,
--成员函数,
-- ...
-- }

Student = {
    --年龄
    age = 1,
    --性别
    sex = true,
    --打印函数1
    Print1 = function()
        print("进入打印函数1")

        print(age)
        --这样打印的age和Student类中的age没有任何关系 打印的age是一个全局变量

        --在表内部函数中 调用类本身的属性或者方法 要指定类
        --类.属性 或 类.方法()
        print(Student.age)
        print(Student.sex)

        print("退出打印函数1")
    end,
    --打印函数2
    Print2 = function(myStudent)
        print("进入打印函数2")

        --可以使用有参函数 把当前类作为一个参数传进来函数中来
        --在函数内部调用类本身的属性或者方法 在内部访问
        print(Student.age)
        print(myStudent.sex)

        print("退出打印函数2")
    end
}

--C#是使用类实例化new出对象 静态成员.出成员
--Lua中是没有实例化new的概念的 类的表现更像是一个类中有很多静态成员

--得到类的成员变量
--直接 类.变量 得到变量
print(Student.age) --1
print(Student.sex) --true

--在类外添加的成员变量
--声明类过后 可以直接在类外 类.变量 = 值 添加成员变量
Student.name = "韬老狮"
print(Student.name) --韬老狮

--使用.调用类的成员方法
Student.Print1()
-- 进入打印函数1
-- nil
-- 1
-- true
-- 退出打印函数1
Student.Print2(Student) --传入当前类作为参数
-- 进入打印函数2
-- 1
-- true
-- 退出打印函数2

--使用.在类外添加的成员方法
--声明类过后 可以直接在类外
-- 类.方法 = function()
--     函数体
-- end
-- 来添加成员方法
Student.Print3 = function()
    print("进入打印函数3")

    print(Student.age)
    print(Student.sex)

    print("退出打印函数3")
end
Student.Print3()
-- 进入打印函数3
-- 1
-- true
-- 退出打印函数3

--使用:调用类的成员方法
--冒号调用方法 会默认把调用者 作为调用的方法的第一个参数传入方法中
Student:Print2() --虽然没有显式的传入Student作为参数 但是因为是:调用函数 已经隐式的传入Student作为参数了
-- 进入打印函数2
-- 1
-- true
-- 退出打印函数2

--使用:在类外添加的成员方法
--声明类过后 可以直接在类外
-- 类:方法 = function()
--     函数体
-- end
-- 来添加成员方法
--使用了:声明方法后 代表方法会有一个默认的参数
--在方法内 通过self来表示默认传入的第一个参数
function Student:Print4() --虽然没有显式的有参数 但是因为是:声明函数 已经隐式的让这个函数有参数了
    print("进入打印函数4")

    print(self.age)
    print(self.sex)

    print("退出打印函数4")
end

-- Student.Print4()--报错 Print4因为是:声明函数 需要传入参数
Student.Print4(Student) --传入了Student类自身作为参数 正常调用
-- 进入打印函数4
-- 1
-- true
-- 退出打印函数4
Student:Print4() --冒号调用方法 会把调用者Student作为第一个参数传进去 正常调用
-- 进入打印函数4
-- 1
-- true
-- 退出打印函数4


print("**********知识点八 表的公共方法************")

-- 插入
t1 = { { age = 1, name = "111" }, { age = 2, name = "222" } }
t2 = { name = "韬老狮", sex = true }
-- table.insert(要插入元素的表,插入的表) 会把插入的表的表作为要插入元素的表作为顺序索引的最后一个元素
print(#t1)        --2
table.insert(t1, t2);
print(#t1)        --3
print(t1[1].name) --111
print(t1[2].name) --222
print(t1[3].name) --韬老狮 代表把t2的的元素插入成功了

--删除
t1 = { { age = 1, name = "111" }, { age = 2, name = "222" }, { name = "韬老狮", sex = true } }
--table.remove(要移除元素的表) 会移除传入的表的最后一个索引的内容
print(#t1)        --3
table.remove(t1)
print(#t1)        --2
print(t1[1].name) --111
print(t1[2].name) --222
print(t1[3])      --nil 最后一个元素被移除了
--table.remove(要移除元素的表, 移除元素索引)
print(#t1)        --2
table.remove(t1, 1)
print(#t1)        --1
print(t1[1].name) --222 name为111的元素被移除了

--排序
t1 = { 5, 2, 4, 3, 1 }
--table.sort(要排序的表) 默认升序排列
table.sort(t1)
for _, v in pairs(t1) do
    print(v)
    -- 1
    -- 2
    -- 3
    -- 4
    -- 5
end
--table.sort(要排序的表,排序规则函数)
-- 排序函数接受两个参数,通常命名为 a 和 b,用于表示待比较的两个元素。
-- 排序函数根据 a 和 b 的比较结果返回 true 或 false,以指示元素的相对顺序。
-- 如果排序函数返回 true,则表示 a 应该在 b 前面。
-- 如果排序函数返回 false,则表示 b 应该在 a 前面。
-- 排序函数必须返回布尔值,且只有 true 或 false。
--降序
table.sort(t1, function(a, b)
    return a > b
end)
for _, v in pairs(t1) do
    print(v)
    -- 5
    -- 4
    -- 3
    -- 2
    -- 1
end
--升序
function AscendingSort(a, b)
    return a < b
end

table.sort(t1, AscendingSort)
for _, v in pairs(t1) do
    print(v)
    -- 1
    -- 2
    -- 3
    -- 4
    -- 5
end

--拼接
t1 = { "123", "456", "789", "10101" }
--table.concat(要拼接的表, "元素间的符号") 返回值是一个拼接好的字符串
str = table.concat(t1, "@@")
print(str) --123@@456@@789@@10101


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏