为什么这在Lua中有效? - 对于k,v in next,t,nil do print(k,v)end

时间:2017-02-17 18:38:55

标签: lua iterator next

我无法绕过这个工作的Lua snipplet。

此:

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参数的方式。{li}
  • 以及为什么需要nil并将其视为有效步骤?

2 个答案:

答案 0 :(得分:3)

要扩展其他答案:

“循环”通用中涉及的值的更具描述性的命名'如下:

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不这样做,而另一个例子是{{1} }甚至完全忽略string.gmatch state并将所有不同的状态保持在一个闭包中(想想'函数'如果你不知道那个(而是)。)

现在,k所做的基本上只是

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 - 来混淆那些对此还不了解的人,或者避免触发{{1 }}。 (为了避免触发pairs / __pairs,您有__index / __newindex,为了避免rawget,您明确地写了rawset。或许您定义__pairs并使用它......)

答案 1 :(得分:1)

所有积分都会转到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()可以被几乎任何完全控制迭代的函数所取代。哇。