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,提问作者無所謂
相关产品推荐
相关产品推荐

