为什么这适用于 Lua? - 对于 k, v in next, t, nil 做 print(k, v) end
Why this works in Lua? - for k, v in next, t, nil do print(k, v) end
我就是无法理解这个有效的 Lua 片段。
这个:
t = {'a', 'b', 'c'}
for k, v in next, t, nil do
print(k, v)
end
Returns这个:
1 a
2 b
3 c
谁能解释一下,
next
如何获取 t
作为参数?
t
如何成为 for
的有效 to
参数
- 以及为什么需要
nil
并将其作为有效步骤接受?
他在评论中的回答全部归功于 Egor。
A for statement like
for var_1, ···, var_n in explist do block end
is equivalent to the code:
do
local f, s, var = explist
while true do
local var_1, ···, var_n = f(s, var)
if var_1 == nil then break end
var = var_1
block
end
end
所以原始语句转化为无限while
循环,不断调用next()
初始参数next(t, nil)
,并且在每次迭代中第二个参数被下一个索引替换在 t
table 中。当最后 next(t, index_n)
returns nil
时,循环中断。
在我看来,这是一种非常强大的遍历 table 的方法,因为 next()
几乎可以替换为任何可以完全控制迭代的函数。哇
扩展一下其他答案:
'generic for loop' 中涉及的值的更具描述性的命名如下:
for k, v1, v2, … in f_step, state, k0 do … end
它会像
一样循环
k,v1,v2,…=f_step(state,k0) ; if k==nil then break end ; k0=k ; --(…for body here…)
k,v1,v2,…=f_step(state,k0) ; if k==nil then break end ; k0=k ; --(…for body here…)
k,v1,v2,…=f_step(state,k0) ; if k==nil then break end ; k0=k ; --(…for body here…)
…
和 f_step 可以随意修改 state
(尽管 pairs
/next
不会那样做,再举一个例子, string.gmatch
甚至完全忽略 state
和 k
并将所有不同的状态保持在一个闭包中(想想 'function' 如果你不还知道这个词)而不是。)
现在,pairs
所做的基本上只是
function pairs( t )
-- (__pairs logic goes here, omitted for brevity)
return next, t, nil
end
和常见的
for k, v in pairs( t ) do … end
基本上扩展到
for k, v in next, t, nil do … end
(除非 t
有一个带有 __pairs
的元表。)
现在有两个原因可以明确地写 next, t, nil
而不是 pairs
– 混淆那些还不知道这件事的人,或者避免触发 __pairs
。 (为了避免触发 __index
/__newindex
,你有 rawget
/rawset
,为了避免 __pairs
,你明确地写了 next, t, nil
。或者也许你定义 function rawpairs( t ) return next, t, nil end
并使用它……)
我就是无法理解这个有效的 Lua 片段。
这个:
t = {'a', 'b', 'c'}
for k, v in next, t, nil do
print(k, v)
end
Returns这个:
1 a
2 b
3 c
谁能解释一下,
next
如何获取t
作为参数?t
如何成为for
的有效 - 以及为什么需要
nil
并将其作为有效步骤接受?
to
参数
他在评论中的回答全部归功于 Egor。
A for statement like
for var_1, ···, var_n in explist do block end
is equivalent to the code:
do local f, s, var = explist while true do local var_1, ···, var_n = f(s, var) if var_1 == nil then break end var = var_1 block end end
所以原始语句转化为无限while
循环,不断调用next()
初始参数next(t, nil)
,并且在每次迭代中第二个参数被下一个索引替换在 t
table 中。当最后 next(t, index_n)
returns nil
时,循环中断。
在我看来,这是一种非常强大的遍历 table 的方法,因为 next()
几乎可以替换为任何可以完全控制迭代的函数。哇
扩展一下其他答案:
'generic for loop' 中涉及的值的更具描述性的命名如下:
for k, v1, v2, … in f_step, state, k0 do … end
它会像
一样循环k,v1,v2,…=f_step(state,k0) ; if k==nil then break end ; k0=k ; --(…for body here…)
k,v1,v2,…=f_step(state,k0) ; if k==nil then break end ; k0=k ; --(…for body here…)
k,v1,v2,…=f_step(state,k0) ; if k==nil then break end ; k0=k ; --(…for body here…)
…
和 f_step 可以随意修改 state
(尽管 pairs
/next
不会那样做,再举一个例子, string.gmatch
甚至完全忽略 state
和 k
并将所有不同的状态保持在一个闭包中(想想 'function' 如果你不还知道这个词)而不是。)
现在,pairs
所做的基本上只是
function pairs( t )
-- (__pairs logic goes here, omitted for brevity)
return next, t, nil
end
和常见的
for k, v in pairs( t ) do … end
基本上扩展到
for k, v in next, t, nil do … end
(除非 t
有一个带有 __pairs
的元表。)
现在有两个原因可以明确地写 next, t, nil
而不是 pairs
– 混淆那些还不知道这件事的人,或者避免触发 __pairs
。 (为了避免触发 __index
/__newindex
,你有 rawget
/rawset
,为了避免 __pairs
,你明确地写了 next, t, nil
。或者也许你定义 function rawpairs( t ) return next, t, nil end
并使用它……)