【问题标题】:What is the boolean interpolation character for string.format function in lualua中string.format函数的布尔插值字符是什么
【发布时间】:2023-04-02 06:40:01
【问题描述】:

我正在寻找 string.format 的布尔插值字符(如标题所示)。
我想要一些能以这种方式工作的东西:

print(string.format("nil == false: %b",(nil==false))

%b 只是一个占位符,你会得到一个错误。我正在寻找'b'。我不能 做吧:

print("nil == false: " .. (nil==false))

因为布尔值不能与字符串连接。我可以这样做:

val=(nil==false)
if val==false then truth="false" else truth="true" end
print("nil==false: ".. truth)

但是工作量太大了。

【问题讨论】:

  • print("nil == false: " .. tostring(nil==false)) 呢?

标签: string lua boolean


【解决方案1】:

如果您想知道如何修改 string.format 使其支持布尔值,您可以使用以下方法:

do
local format = string.format
function string.format(str, ...)
  local args = {...}
  local boolargs = {}
  str = str:gsub("%%b", "%%%%b")
  for i = #args, 1, -1 do
    if type(args[i]) == "boolean" then
      table.insert(boolargs, 1, args[i])
      table.remove(args, i)
    end
  end
  str = format(str, unpack(args))

  local j = 0
  return (str:gsub("%%b", function(spec) j = j + 1; return tostring(boolargs[j]) end))
end
end

print(string.format("%s is %b", "nil == false", nil==false))

这可能有点令人困惑。这个想法是 gsub 字符串中的所有 "%b" 并用双转义 %%b 替换它,因此格式不会尝试解释它。我们让string.format 做它的事情,然后我们自己手动处理%b 的结果。

【讨论】:

  • @Segfault 映射到格式规范的实际项目在传入的... 部分中。我们必须从其中删除所有布尔值,然后再将其提供给真正的string.format。但是我们还需要保留那些删除的布尔值,以便我们知道以后要替换什么。 varargs ... 不是 lua 中的一流构造,所以我将它包装到一个表格中以便于操作。
  • 我必须说,您的回答至少可以说令人印象深刻。为什么g=... 存储传递给函数的第一个参数,而f={...} 存储arg 表。另外,你为什么要做local args={...} 却已经有一个隐含的arg 表被传递了?
  • 我知道了,谢谢。我的意思是,例如:function func(...) g=... f={...} print(f) -- table: 0076B070 print(g) -- "first arg" end func("first arg","second arg") 为什么fg 不一样?价值调整?
  • @Segfault 那是因为f = {...} 在包装参数的过程中创建了一个新表。 OTOH g = ...,右侧有 1 个或多个参数,但左侧只能容纳一个参数。如果你说g, h, i = ...,那么你从右侧取出前3个参数,并将它们分别放入g, h, i
【解决方案2】:

嗯,首先你应该尝试阅读the relevant section of the manual。这会让你发现布尔值没有格式说明符。

greatwolf 建议的是一种解决方案,即将值显式转换为字符串。如果你的真值有可能是nil,但你想输出为false,这个技巧很有用:

truth = nil
print("nil==false: ".. tostring( not not truth ))

这样nilfalse 都将显示为false

编辑(回答评论)

在 Lua 5.2 中,%s 说明符在内部使用 tostring 自动将参数转换为字符串。因此:

print( string.format( "%s  %s  %s", true, nil, {} ) )

打印:

true  nil  table: 00462400

否则您可以创建自己的格式化函数包装string.format

 local function myformat( fmt, ... )
    local buf = {}
     for i = 1, select( '#', ... ) do
         local a = select( i, ... )
         if type( a ) ~= 'string' and type( a ) ~= 'number' then
             a = tostring( a )
         end
         buf[i] = a
     end
     return string.format( fmt, unpack( buf ) )
 end


 print( myformat( "%s  %s  %s", true, nil, {} ) )

【讨论】:

  • 这很公平,考虑到它比其他选择更短。不过我很好奇,是否可以使用CC++ 为布尔值添加/扩展string.format 的新字符?
  • @Sefault 当然有可能,但有点牵涉。请参阅我的回复以了解一种方法。
  • @Segfault 如果你的 C 语言技能不错,你可以修改源代码。我在上面的编辑中显示了一种更简单的方法。如果您真的想要一个新的格式说明符,请参阅 greatwolf 的答案,但恕我直言,这有点矫枉过正。
  • 您的方法似乎有效。 select 是做什么的? lua 参考不是很有帮助。另外,为什么@greatwolf 的回答太过分了?这是相当令人印象深刻和聪明的海事组织。
  • @Segfault select 函数为处理传入的可变参数提供了一些便利。select('#', ...) 返回... 部分的参数计数。 select(i, ...) 返回第 i 个元素及以后。
猜你喜欢
  • 1970-01-01
  • 2011-01-29
  • 2019-09-30
  • 2015-11-27
  • 1970-01-01
  • 2019-08-17
  • 2011-03-17
  • 1970-01-01
  • 2015-02-19
相关资源
最近更新 更多