You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Lua中for循环为何使用匿名函数而非直接调用string.find?

Lua string.split中for循环使用匿名函数的原因

先看这个string.split的实现代码:

function string.split(input, delimiter)
    input = tostring(input)
    delimiter = tostring(delimiter)
    if (delimiter=='') then return false end
    local pos,arr = 0, {}
    -- for each divider found
    for st,sp in function() return string.find(input, delimiter, pos, true) end do
        table.insert(arr, string.sub(input, pos, st - 1))
        pos = sp + 1
    end
    table.insert(arr, string.sub(input, pos))
    return arr
end

为什么这里要用匿名函数包裹string.find,而不是直接写成下面这样?

for st,sp in string.find(input, delimiter, pos, true) do
    table.insert(arr, string.sub(input, pos, st - 1))
    pos = sp + 1
end

核心原因:Lua泛型for的迭代逻辑

Lua的泛型for循环需要的是能多次调用、每次返回新迭代值的迭代器函数,而不是单次调用的结果。

  • 直接调用string.find(...)的话,这个函数只会执行一次,返回第一次匹配到的分隔符位置,之后循环就没有新的返回值了,只会跑一次就结束,根本没法遍历所有分隔符。
  • 用匿名函数包裹后,每次循环都会执行这个匿名函数:它会拿着当前已经更新过的pos(上次匹配结束后的位置)去调用string.find,这样就能从上次结束的地方继续查找下一个分隔符,直到string.find返回nil(找不到更多分隔符),循环才会终止。

举个实际例子:如果输入是"a,b,c",分隔符是,:

  • 直接用string.find的话,只会得到第一个,的位置(2,2),循环只执行一次,最后结果是{"a", ",b,c"},完全不符合split的预期。
  • 用匿名函数的话,第一次调用找到(2,2),pos变成3;第二次调用从位置3开始找,得到(4,4),pos变成5;第三次调用从5开始找,找不到返回nil,循环结束,最后插入"c",得到正确的{"a","b","c"}。

另外,匿名函数还能捕获外部的input、delimiter和pos变量,每次调用都能使用最新的pos值,完美实现了持续查找的逻辑。

内容的提问来源于stack exchange,提问作者無所謂

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 03:05:33