Lua 如何区分 1 和 1.0?

4

我有一个配置脚本,用户可以输入绝对值或百分比值。

绝对值写为介于0.0和1.0之间的数值,而百分比值则写为0到100。

如何区分1和1.0? 如果我使用字符串,那么肯定没有问题... 我希望保持这个配置简单,不必依赖字符串。

这真的可能吗?

总结:

a = 1
b = 1.0

如何判断ab不是相同类型。

编辑 配置文件看起来像这样:

local config = {}

-- A lot of comments describing how to configure

config.paramA = 1
config.paramB = 1.0

return config

在我的处理脚本中,我是这样读取配置文件的:
config = require 'MyConfigFile'

config.paramA
config.paramB

你是如何读取文件的?在将其转换为数字进行正常使用之前,你能否仅使用字符串值?然后以某种方式“标记”该值? - Etan Reisner
可能的重复问题: https://dev59.com/y0fRa4cB1Zd3GeqP6iSK - jean
@jean 不是从C/C++访问userdata,我需要在Lua脚本中处理一些Lua类型的数据。 - Max Kielland
2
如果用户想要写入带小数的百分比值,例如12.5怎么办?您是否考虑过只允许绝对值或百分比?您说您的目标是简单易用,但在我看来,1和1.0有不同的含义,这非常令人困惑。 - hugomg
如果这是一个字符串,那么这根本不是问题,我只是想知道是否可以在没有字符串的情况下实现。正如@Youka所提到的,在Lua 5.3中是可能的。 - Max Kielland
4个回答

7
随着Lua 5.3的推出,引入了整数数据类型,可以区分整数和浮点数,并在某些情况下提供更好的性能。math.type是获取数字子类型的函数。请注意,保留HTML标签。
local x = 1.0
print(math.type(x)) -- float
x = 1
print(math.type(x)) -- integer

如果您的百分比值也应该是浮点数,William已经说过了:"数字就是数字"。您必须为您的数字添加额外的信息以进行区分,例如将其打包在带有标识符的表中。因为您只有两种情况,所以布尔值将是一种廉价的解决方案。

这确实是一个有趣的解决方案,但我忘记添加标签Lua 5.2了。我无法控制使用的Lua版本 :( - Max Kielland
我将此标记为解决方案,因为在Lua 5.3中至少是可能的。然而,对于我的问题,我不能使用这个解决方案。我必须退而求其次,使用字符串代替。 - Max Kielland
如果你关心性能,执行字符串到数字的转换并不是一个很聪明的解决方案。如果你的Lua解释器是luajit,那么一个表甚至可能被优化成比你的字符串解决方案更便宜的东西。 - Youka

4
PIL 中可以看到,数字就是数字,因此在使用时无法区分 11.0,因为它们具有相同的类型。
解决这个问题的方法是使用包含值和类型的表格:
config.paramA = { 1, 'i' }
config.paramB = { 1.0, 'd' }

或者使用字符串,在将其转换为整数之前进行解析:

config.paramA = '1'
config.paramB = '1.0'

正如我之前所说,如果它是一个字符串,就不会有任何问题;)表格是一个有趣的解决方案,但它使问题更加复杂。因此,对于用户来说,只有'100%'或'1'的字符串会更容易些。 - Max Kielland

2

在 Lua 5.1 和 5.2 中没有区别,这一点可以从 luacluac -i)的输出中看出,因为 local a, b = 1, 1.0 会生成以下代码:

main <1.lua:0,0> (3 instructions, 12 bytes at 007D04E8)
0+ params, 2 slots, 0 upvalues, 2 locals, 1 constant, 0 functions
    1   [1] LOADK       0 -1    ; 1
    2   [1] LOADK       1 -1    ; 1
    3   [1] RETURN      0 1

Lua 5.3允许使用math.type来区分两者,因为它们具有不同的子类型。
作为解决您特定问题的方法,如果您真的想将其变成非整数,可以向数字添加一个非常小的增量:1.0000001而不是1.0

这也是一个有趣的解决方案,但它会让用户更难理解为什么他们必须添加那么多小数位。我想我会使用下一个备选方案,改用带有百分号的字符串。 - Max Kielland

1

一些建议:

1)仅允许两种格式之一

2)使用函数使格式明确

config.paramA = percent(1.9)
config.paramB = portion(1)

这些功能可以创建带有类型信息的表,或将值转换为一致的类型。


我也喜欢这个想法 :) 它干净简单易懂。 - Max Kielland
2
另一个建议:使用不同的键。例如,config.paramA = 1config.paramA_percent = 1。使用一些元表技巧,两个都可以写入相同的字段。 - siffiejoe

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