Lua表

       表(Table)是Lua中唯一的数据结构机制,本节将全面讲解表的创建、访问、遍历、元表等核心概念,特别针对Android开发进行优化说明。

1. 表的基础操作

1.1 创建表

-- 空表
local emptyTable = {}

-- 数组式初始化
local colors = {"red", "green", "blue"}

-- 字典式初始化
local person = {
    name = "张三",
    age = 25,
    [1] = "数组部分"  -- 混合写法
}

-- 嵌套表结构
local androidUI = {
    layout = "LinearLayout",
    attributes = {
        orientation = "vertical",
        width = "match_parent"
    }
}

1.2 访问表元素

-- 数组部分访问(索引从1开始)
print(colors[1])  -- 输出"red"

-- 字典部分访问
print(person.name)    -- 输出"张三"
print(person["age"])  -- 输出25

-- 安全访问(避免nil错误)
local width = androidUI.attributes.width or "wrap_content"

2. 表操作函数

2.1 常用表操作

local t = {3, 1, 4, 2}

-- 插入元素
table.insert(t, 5)       -- 末尾插入
table.insert(t, 2, 1.5)  -- 指定位置插入

-- 移除元素
table.remove(t, 3)  -- 移除第三个元素

-- 排序
table.sort(t)  -- 默认升序
table.sort(t, function(a, b) return a > b end)  -- 自定义排序

-- 连接
print(table.concat(t, ", "))  -- 输出"3, 1.5, 2, 1"

2.2 高级操作

-- 深拷贝函数
function deepCopy(orig)
    local copy = {}
    for k, v in pairs(orig) do
        if type(v) == "table" then
            v = deepCopy(v)
        end
        copy[k] = v
    end
    return copy
end

-- 表合并
function merge(t1, t2)
    for k, v in pairs(t2) do
        t1[k] = v
    end
    return t1
end

3. 表遍历

3.1 遍历方式

local config = {
    resolution = "1080p",
    fps = 60,
    quality = "high",
    [5] = "test"
}

-- ipairs遍历数组部分(忽略非连续数字键)
for i, v in ipairs(config) do
    print(i, v)  -- 只输出5 test
end

-- pairs遍历所有元素
for k, v in pairs(config) do
    print(k, v)  -- 输出所有键值对
end

-- 按需选择遍历方式
if #config > 0 then  -- 判断是否有数组部分
    -- 处理数组
end

3.2 性能优化

Android开发建议:

4. 元表(Metatable)

4.1 元表基础

-- 创建元表
local mt = {
    __index = function(t, k)
        print("访问不存在的键:", k)
        return "默认值"
    end,
    __newindex = function(t, k, v)
        rawset(t, k, v)  -- 必须使用rawset
        print("设置了新键:", k, v)
    end
}

local t = setmetatable({}, mt)
print(t.name)  -- 触发__index
t.age = 25     -- 触发__newindex

4.2 运算符重载

-- 向量运算示例
local Vector = {}
Vector.__index = Vector

function Vector.new(x, y)
    return setmetatable({x = x, y = y}, Vector)
end

function Vector.__add(a, b)
    return Vector.new(a.x + b.x, a.y + b.y)
end

local v1 = Vector.new(1, 2)
local v2 = Vector.new(3, 4)
local v3 = v1 + v2  -- 调用__add
print(v3.x, v3.y)   -- 输出4 6

5. Android开发实践

5.1 表作为配置

-- UI配置表
local buttonStyle = {
    textColor = "#FFFFFF",
    backgroundColor = "#5e72e4",
    textSize = 16,
    onClick = function(view)
        print("按钮被点击")
    end
}

-- 应用样式
function applyStyle(view, style)
    view:setTextColor(style.textColor)
    view:setBackgroundColor(style.backgroundColor)
    view:setOnClickListener(style.onClick)
end

5.2 表与Java交互

-- Lua表转为Java Map
local map = HashMap()
map:put("name", "张三")
map:put("age", 25)

-- Java Map转为Lua表
local javaMap = javaObject:getMap()
local luaTable = {}
for entry in javaMap:entrySet():iterator() do
    luaTable[entry:getKey()] = entry:getValue()
end

注意事项:

6. 性能优化

6.1 表预分配

-- 不好的做法(动态增长)
local t = {}
for i = 1, 10000 do
    t[i] = i  -- 反复重新分配内存
end

-- 好的做法(预分配)
local t = {}
for i = 1, 10000 do
    t[i] = 0  -- 先填充默认值
end
for i = 1, 10000 do
    t[i] = i  -- 然后赋值
end

6.2 弱引用表

-- 创建弱引用表
local weakTable = setmetatable({}, {__mode = "v"})

-- 添加元素
weakTable[1] = "临时数据"

-- 内存不足时自动回收
collectgarbage()
print(weakTable[1])  -- 可能为nil

7. 实用模式

7.1 面向对象

-- 类定义
local Class = {}
Class.__index = Class

function Class.new(name)
    local self = setmetatable({}, Class)
    self.name = name
    return self
end

function Class:sayHello()
    print("Hello, "..self.name)
end

-- 使用
local obj = Class.new("Lua")
obj:sayHello()

7.2 模块模式

-- 定义模块
local module = {}

function module.func1()
    print("功能1")
end

-- 私有函数
local function privateFunc()
    -- 内部实现
end

return module