2017-02-17 70 views
2

我只是不能包裹我的头围绕这个工作Lua snipplet。为什么这在Lua中有效? - 对于K,V在下一个,T,无打印(K,V)结束

此:

t = {'a', 'b', 'c'} 
for k, v in next, t, nil do 
    print(k, v) 
end 

返回此:

1 a 
2 b 
3 c 

有人能解释,

  • 如何next得到t作为它的参数?
  • 如何t是一个有效的to参数为for
  • 为什么nil需要和接受有效的一步?
+0

这是相当K表(左数字索引)获取下一个和v得到t [k](右边的值),其余的不知道 – Kaddath

+4

Lua在为[loop]执行[generic]时将't'作为'next'的参数(https://www.lua .ORG /手动/ 5.3/manual.html#3.3.5)。这与数字“for”循环不同。 –

+0

是的,现在我明白了。这不是一个数字,而是一个通用的。 'next,t,nil'部分被评估为'next(t,nil)',现在突然变得有意义......感谢Egor。 –

回答

3

要扩展位上其他答案:

更具描述性的参与“一般的for循环”的值的命名如下:

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甚至完全忽略了statek,而是在关闭中保持所有变化的状态(如果您还不知道该项,请考虑“函数”)。)


现在,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公顷S采用__pairs一元表)

现在有两个原因,为什么您可能会明确写入next, t, nil,而不是pairs - 蛊惑人心不知道是谁做这个呢,还是避免引发__pairs。 (为了避免触发__index/__newindex,你有rawget/rawset,避免__pairs,你明确写入next, t, nil,或者你定义function rawpairs(t) return next, t, nil end和使用......)

0

所有学分请在Egor之间回答他的回答。

Lua 5.3 manual

for语句像

for var_1, ···, var_n in explist do block end 

相当于代码:

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表中的下一个索引替换。当最终next(t, index_n)返回nil时,循环中断。

在我看来,这似乎是一种非常强大的遍历表的方式,因为next()可以被完全控制迭代的任何函数替代。哇。

相关问题