如何启用Lua基本类型之间的算术运算?

流行的脚本语言允许进行如下表达式

true*5>10.3*false

其中 true 是 1,false 是 0,除 0 以外的任何数也是 true

你能在 Lua 中做到这一点吗?

目前我正在将所有操作数包装成一个表,并使用 __sub 这样的元方法来启用所述功能,但它产生冗长的代码和开销

点赞
用户107090
用户107090

是的。请看下面的代码。您可以为其他算术运算添加类似的元方法。

local function b2n(x)
    if x==false then return 0 end
    if x==true  then return 1 end
    return x
end

debug.setmetatable(false,{
    __mul=function(x,y) return b2n(x)*b2n(y) end
})

print(true*5 > 10.3*false)
2017-07-01 10:59:54
用户805875
用户805875

一种方法可能有所助益(虽然不如 lhf 描述的“适当方式”),如下:

目前,我将所有操作数都包装成表,并使用像 __sub 这样的元方法以启用该功能,但它会生成冗长的代码和开销,并且

我无法在我的环境中访问 debug 表。

是拥有强制类型转换值的函数,如 NB 等...

function N( x )
   local ty = type( x )
   if ty == "number" then  return x  end
   if ty == "boolean" then  return x and 1 or 0  end
   -- and so on for other types you need to handle
end

然后你可以说 B(v) and (N(x)*N(y) > N(z)+N(w)) 或者类似的内容。虽然有很多函数调用,但它可能比将所有内容包装在表中更快,并且(取决于如何/在何处进行包装)这也可能更易读。

如果你正在编写类似库的代码,在顶层(在暴露的库函数中,在接收值后的位置/在通常进行类型检查的位置右侧)进行强制类型转换意味着你始终拥有适合库内的合适类型值,并且不需要在内部使用这些强制类型转换函数。因此,在入口点处实质上只是进行类型检查/自动类型转换,而后面则是正常的代码。

如果你要为方便在你的代码内部使用它(例如,将比较结果解释为算术运算的0或1),你将知道哪些需要包装,其余内容可以保持不包装。

无论哪种情况,这可能比将所有内容都包装在表中更快/更易读。

2017-07-01 20:55:51