预处理 ... 输入 - 错误参数 #2 到 'format'(无值)
Pre-process ... input - bad argument #2 to 'format' (no value)
我有一个场景,我想将输入输入到 printf 实现并预处理参数。我的目标是获取输入,在必要时处理变量参数 (...
),然后将其输入 string.format。我遇到的问题是数据在传递时会“丢失”。我发现 ...
中的 nil 值没有传入。例如,如果正常 运行 通过 nil, false, false
,则调用路径中的后续下线函数只会看到 false, false
。当转换为内部 table ({...}
) 进行处理时,我在这里缺少什么来保留数据?
编辑:我的初步评估不正确。 nil 永远不会被保留(即使在 printf 中)。如果打印 ...
,则 table 可以为空(对于所有 nil)或仅在包含“真实”数据的位置具有索引值(例如 TablePrint 给出 { [2] = false, [3 ] = 假})
这 是 运行 在游戏中,但我可以在不使用任何游戏数据的情况下复制行为。
local function TablePrint (data, indent)
if not indent then indent = 0 end
local output = string.rep(" ", indent) .. "{\r\n"
indent = indent + 2
for k, v in pairs(data) do
output = output .. string.rep(" ", indent)
if (type(k) == "number") then
output = output .. "[" .. k .. "] = "
elseif (type(k) == "string") then
output = output .. k .. "= "
end
if (v == nil) then
output = output .. 'nil' .. ",\r\n"
elseif (v == NULL) then
output = output .. 'NULL' .. ",\r\n"
elseif (type(v) == "number") then
output = output .. v .. ",\r\n"
elseif (type(v) == "string") then
output = output .. "\"" .. v .. "\",\r\n"
elseif (type(v) == "table") then
output = output .. TablePrint(v, indent + 2) .. ",\r\n"
else
output = output .. "\"" .. tostring(v) .. "\",\r\n"
end
end
output = output .. string.rep(" ", indent-2) .. "}"
return output
end
local function NormalizeValue(v)
local output
if (v == nil) then
output = 'nil'
elseif (v == NULL) then
output = 'NULL'
elseif (type(v) == "number" or type(v) == "string") then
output = v
elseif (type(v) == "table") then
output = TablePrint(v)
else
output = tostring(v)
end
return output
end
local function NormalizeArgs(...)
local args = {...}
--print(TablePrint(args))
local normalizedArgs = {}
for _,v in ipairs(args) do
table.insert(normalizedArgs, NormalizeValue(v))
end
return unpack(normalizedArgs)
end
local function printf(message, ...)
--print(TablePrint({...}))
local output
if (type(message) == "number") then
output = message
elseif (type(message) == "string") then
output = string.format(message, NormalizeArgs(...))
--this call to string.format succeeds if used
--output = string.format(message, ...)
elseif (type(message) == "table") then
output = TablePrint(message)
else
output = tostring(message)
end
print(output)
end
--this line fails since nil isn't preserved across call boundaries
--printf('initial conditions, cursor: %s, confirm window: %s, isfinished: %s', nil, nil, nil)
--this line fails since nil isn't preserved across call boundaries
printf('initial conditions, cursor: %s, confirm window: %s, isfinished: %s', nil, false, false)
--this will succeed
printf('initial conditions, cursor: %s, confirm window: %s, isfinished: %s', false, false, false)
--in the normal impl the final parameter is supplied by a call to a local function
printf('initial conditions, cursor: %s, confirm window: %s, isfinished: %s', gamelib.Cursor.ID(), gamelib.Window('Confirm').Open(), nil)
您可以使用select来全面检查...
。递归地 return 多个值可能比创建 table 只是为了解压它更容易:
local function NormalizeArgs(...)
if select('#', ...) > 0 then
return NormalizeValue(select(1, ...)), NormalizeArgs(select(2, ...))
end
end
我有一个场景,我想将输入输入到 printf 实现并预处理参数。我的目标是获取输入,在必要时处理变量参数 (...
),然后将其输入 string.format。我遇到的问题是数据在传递时会“丢失”。我发现 ...
中的 nil 值没有传入。例如,如果正常 运行 通过 nil, false, false
,则调用路径中的后续下线函数只会看到 false, false
。当转换为内部 table ({...}
) 进行处理时,我在这里缺少什么来保留数据?
编辑:我的初步评估不正确。 nil 永远不会被保留(即使在 printf 中)。如果打印 ...
,则 table 可以为空(对于所有 nil)或仅在包含“真实”数据的位置具有索引值(例如 TablePrint 给出 { [2] = false, [3 ] = 假})
这 是 运行 在游戏中,但我可以在不使用任何游戏数据的情况下复制行为。
local function TablePrint (data, indent)
if not indent then indent = 0 end
local output = string.rep(" ", indent) .. "{\r\n"
indent = indent + 2
for k, v in pairs(data) do
output = output .. string.rep(" ", indent)
if (type(k) == "number") then
output = output .. "[" .. k .. "] = "
elseif (type(k) == "string") then
output = output .. k .. "= "
end
if (v == nil) then
output = output .. 'nil' .. ",\r\n"
elseif (v == NULL) then
output = output .. 'NULL' .. ",\r\n"
elseif (type(v) == "number") then
output = output .. v .. ",\r\n"
elseif (type(v) == "string") then
output = output .. "\"" .. v .. "\",\r\n"
elseif (type(v) == "table") then
output = output .. TablePrint(v, indent + 2) .. ",\r\n"
else
output = output .. "\"" .. tostring(v) .. "\",\r\n"
end
end
output = output .. string.rep(" ", indent-2) .. "}"
return output
end
local function NormalizeValue(v)
local output
if (v == nil) then
output = 'nil'
elseif (v == NULL) then
output = 'NULL'
elseif (type(v) == "number" or type(v) == "string") then
output = v
elseif (type(v) == "table") then
output = TablePrint(v)
else
output = tostring(v)
end
return output
end
local function NormalizeArgs(...)
local args = {...}
--print(TablePrint(args))
local normalizedArgs = {}
for _,v in ipairs(args) do
table.insert(normalizedArgs, NormalizeValue(v))
end
return unpack(normalizedArgs)
end
local function printf(message, ...)
--print(TablePrint({...}))
local output
if (type(message) == "number") then
output = message
elseif (type(message) == "string") then
output = string.format(message, NormalizeArgs(...))
--this call to string.format succeeds if used
--output = string.format(message, ...)
elseif (type(message) == "table") then
output = TablePrint(message)
else
output = tostring(message)
end
print(output)
end
--this line fails since nil isn't preserved across call boundaries
--printf('initial conditions, cursor: %s, confirm window: %s, isfinished: %s', nil, nil, nil)
--this line fails since nil isn't preserved across call boundaries
printf('initial conditions, cursor: %s, confirm window: %s, isfinished: %s', nil, false, false)
--this will succeed
printf('initial conditions, cursor: %s, confirm window: %s, isfinished: %s', false, false, false)
--in the normal impl the final parameter is supplied by a call to a local function
printf('initial conditions, cursor: %s, confirm window: %s, isfinished: %s', gamelib.Cursor.ID(), gamelib.Window('Confirm').Open(), nil)
您可以使用select来全面检查...
。递归地 return 多个值可能比创建 table 只是为了解压它更容易:
local function NormalizeArgs(...)
if select('#', ...) > 0 then
return NormalizeValue(select(1, ...)), NormalizeArgs(select(2, ...))
end
end