从“在Lua中编程” 一章中的7.1 –迭代器和闭包看来,for foo in bar循环所需要bar的类型必须是类型(使用Java类型表示)Supplier<Tuple>,并且the for-in将继续调用bar直到返回nil。
因此,例如:
for k,v in pairs( tables ) do
print( 'key: '..k..', value: '..v )
end
Run Code Online (Sandbox Code Playgroud)
表示pairs具有的类型Function<Table,Supplier<Tuple>>。
我想创建一个行为类似的函数,pairs 只是它跳过元组,其中第一个参数以下划线(即_)开头。
local function mypairs( list )
local --[[ Supplier<Tuple> ]] pairIterator = pairs( list )
return --[[ Supplier<Tuple> ]] function ()
while true do
local key, value = pairIterator()
if key == nil then
return nil
elseif key:sub(1,1) ~= '_' then
return key, value
end
end
end
end
Run Code Online (Sandbox Code Playgroud)
但是因为它不起作用
--[[should be: Supplier<Table>]] pairIterator = pairs({ c=3; b=2; a=1 })
Run Code Online (Sandbox Code Playgroud)
当我叫它
pairIterator()
Run Code Online (Sandbox Code Playgroud)
它返回
stdin:1: bad argument #1 to 'pairIterator' (table expected, got no value)
stack traceback:
[C]: in function 'pairIterator'
stdin:1: in main chunk
[C]: in ?
Run Code Online (Sandbox Code Playgroud)
但
pairIterator({ c=3; b=2; a=1 })
Run Code Online (Sandbox Code Playgroud)
退货
Lua>pairIterator({ c=3; b=2; a=1 })
c 3
Run Code Online (Sandbox Code Playgroud)
您的基本问题是您正在使用Java逻辑处理Lua问题。Java和Lua是具有不同结构的不同语言,因此认识到这一点很重要。
pairs没有返回值;它具有多个返回值。这是Java完全缺乏的概念。A Tuple是可以存储和操作多个值的单个值。Lua函数可以返回多个值。从语法和语义上讲,这不同于返回包含多个值的表。
基于迭代器的for语句将多个值作为其输入,而不是多个值的表或容器。具体来说,它存储3个值:一个迭代器函数,一个状态值(用于保留调用之间的状态)和一个初始值。
因此,如果您想模仿pairs的行为,则需要能够存储和操纵其多个返回值。
第一步是存储pairs实际返回的内容:
local f, s, var = pairs(list)
Run Code Online (Sandbox Code Playgroud)
您正在创建一个新的迭代器函数。所以,你需要返回,但是你还需要退回s,并var说pairs回报。您的return语句应如下所示:
return function (s, var)
--[[Contents discussed below]]
end, s, var --Returning what `pairs` would return.
Run Code Online (Sandbox Code Playgroud)
现在,在函数内部,您需要f使用s和进行调用var。此函数将返回键/值对。您需要正确处理它们:
return function (s, var)
repeat
local key, value = f(s, var)
if(type(key) ~= "string") then
--Non-string types can't have an `_` in them.
--And no need to special-case `nil`.
return key, value
elseif(key:sub(1, 1) ~= '_') then
return key, value
end
until true
end, s, var --Returning what `pairs` would return.
Run Code Online (Sandbox Code Playgroud)