Lua函数

       函数是Lua编程的核心构建块,本节将全面讲解函数的定义、参数传递、返回值、作用域以及高级特性,特别针对Android开发进行优化说明。

1. 函数基础

1.1 函数定义

-- 全局函数定义
function add(a, b)
    return a + b
end

-- 局部函数定义
local function subtract(a, b)
    return a - b
end

-- 匿名函数赋值
local multiply = function(a, b)
    return a * b
end

1.2 函数调用

-- 直接调用
local sum = add(10, 20)

-- 方法调用(使用冒号)
local str = "hello"
str:upper()  -- 等价于 string.upper(str)

-- 安全调用(避免nil错误)
local result = (type(func) == "function") and func() or nil

2. 参数处理

2.1 参数传递规则

-- 基本类型是值传递
local function change(num)
    num = 100  -- 不影响外部变量
end

local x = 50
change(x)
print(x)  -- 输出50

-- 表类型是引用传递
local function modify(tbl)
    tbl.key = "new"  -- 修改会影响原始表
end

local t = {key = "old"}
modify(t)
print(t.key)  -- 输出"new"

2.2 可变参数(...)

function join(separator, ...)
    local result = ""
    local args = {...}
    for i, v in ipairs(args) do
        if i > 1 then result = result .. separator end
        result = result .. v
    end
    return result
end

print(join(", ", "a", "b", "c"))  -- 输出"a, b, c"

Android开发注意: 可变参数在事件回调中很有用,但参数过多会影响性能,建议超过5个参数时改用table传递。

3. 返回值

3.1 多返回值

-- 模拟Android获取View尺寸
function getViewSize(view)
    return view.width, view.height
end

-- 接收所有返回值
local w, h = getViewSize({width=1080, height=1920})

-- 忽略部分返回值
local _, height = getViewSize({width=720, height=1280})

3.2 错误处理模式

-- Android文件读取示例
function readFile(path)
    local file = io.open(path)
    if not file then
        return nil, "文件不存在: "..path
    end
    local content = file:read("*a")
    file:close()
    return content
end

-- 使用模式
local content, err = readFile("/sdcard/data.txt")
if not content then
    print("错误:", err)
end

4. 函数高级特性

4.1 闭包(Closure)

-- Android点击计数器
function createCounter()
    local count = 0
    return {
        increment = function()
            count = count + 1
            return count
        end,
        reset = function()
            count = 0
        end
    }
end

local counter = createCounter()
button.onClick = function()
    print("点击次数:", counter.increment())
end

4.2 尾调用优化

-- 尾递归实现列表遍历
function foreach(list, func, index)
    index = index or 1
    if index > #list then return end
    func(list[index])
    return foreach(list, func, index + 1)  -- 尾调用
end

-- 不会栈溢出
foreach({1,2,3}, print)

5. 函数与表

5.1 表方法定义

-- Android样式定义
local styles = {
    primaryColor = "#5e72e4",
    textSize = 16
}

function styles:apply(view)
    view:setBackgroundColor(self.primaryColor)
    view:setTextSize(self.textSize)
end

-- 使用
local button = getView()
styles:apply(button)

5.2 __call元方法

-- 创建可调用对象
local timer = setmetatable({
    interval = 1000,
    callback = function() end
}, {
    __call = function(self)
        android.postDelayed(self.callback, self.interval)
    end
})

-- 像函数一样调用
timer()  -- 启动定时器

6. Android开发实践

6.1 Java方法调用

-- 调用静态方法
local Context = luajava.bindClass("android.content.Context")
local vibrator = Context:getSystemService(Context.VIBRATOR_SERVICE)

-- 设置回调
local listener = {
    onSuccess = function(data) print("成功:", data) end,
    onError = function(err) print("错误:", err) end
}

javaObject:setListener(listener)

6.2 性能优化

关键建议:

7. 调试技巧

7.1 调试信息获取

-- 获取函数信息
local info = debug.getinfo(add)
print("函数定义在:", info.short_src, "第", info.linedefined, "行")

-- 跟踪调用
debug.traceback()  -- 打印调用栈

7.2 性能分析

-- 简单性能测试
local start = os.clock()
for i = 1, 1e6 do add(i, i) end
print("耗时:", os.clock() - start, "秒")