在Lua中将布尔值转换为数字

10

有没有一种方法可以在Lua中用true获得1,用false获得0? tobool可以将1或0转换为true或false,但是tonumber在使用true或false时会返回nil值。

3个回答

22
你可以像三元运算符一样组合andor子句。
function bool_to_number(value)
  return value and 1 or 0
end

1
这是否可以在不使用函数的情况下完成?就像在print()中一样。 - Hell Protection
1
@HellProtection print(value and 1 or 0) @HellProtection print(value and 1 or 0) - hjpotter92
需要注意的是,这个解决方案(虽然在大多数情况下实用)将任何值视为真,并将nil视为false,这可能不是OP想要的,如果是这种情况,lhf的解决方案更准确。 - tonypdmtr

9
你也可以这样做:
bool_to_number={ [true]=1, [false]=0 }

print(bool_to_number[value])

或者是这样的:
debug.setmetatable(true, {__len = function (value) return value and 1 or 0 end})

print(#true)
print(#false)

5
为什么呢?它更愿意将此属性视为这些语言的怪癖。当然你可以滥用它,但我认为任何语言都不应该有这样的意图。如果你需要这个功能,我的第一印象是你正在做一些可能有更好方法的事情。 - pschulz
1
@pschulz - 让我重申一下:布尔值应该有序以保持一致性。也就是说,适用于任何有序集合(数字、字符串、可比较的用户对象等)的任何函数也应该适用于布尔值。但是目前在Lua中,a < b会引发“尝试比较两个布尔值”的错误,这是语言设计上的一个缺陷。明显的解决方法(not a) and b并不能解决将布尔值视为具有一致语法的有序集合的问题。 - Egor Skriptunoff
4
@EgorSkriptunoff 有趣,我从未这样看过。我能理解你的观点,但我仍然不同意。3比1大,任何人都能看出来,这“很合理”。如果考虑词典排序之类的东西,“foo” > “bar”。但是我无法理解真比假大。它不是。它也不是更小,问错了问题。此外:我从未对布尔值进行排序,也无法想象为什么我要这样做。如果需要,我会编写一个比较函数。 - pschulz
1
@pschulz - 是的,布尔值必须有它们自己的词典排序。很高兴你理解了它。 - Egor Skriptunoff
1
@pschulz说:“我从来没有对布尔值进行过排序,也想不出为什么要这样做。” 一个常见的情况是根据布尔属性对对象集合进行排序。例如,您希望在退役产品之前显示活动产品,因此按isActive降序排序。 - MarredCheese
显示剩余3条评论

2

代码片段翻译

hjpotter92的答案将任何非nil值视为true值(返回1)。而这个代码片段只将true或false作为true值。

local value = true
print(value == true and 1 or value == false and 0)
-- we add the false check because it would drop 0 in case it was nil

如果您想使用函数,这是它。
local value = true
local function bool_to_number(value)
 return value == true and 1 or value == false and 0
end

print(bool_to_number(value))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接