返回首页

教程导航

返回首页

🏷️ 标签(1)

🗂️ 分类(1)

第 4 章 运算符与表达式

第 4 章 运算符与表达式

Lua 的表达式由值、变量、函数调用和运算符组成。理解求值顺序与真值规则,是避免隐蔽 Bug 的基础。

算术与位运算符

算术运算

local a, b = 10, 3

print(a + b)  -- 13
print(a - b)  -- 7
print(a * b)  -- 30
print(a / b)  -- 3.3333333333333
print(a // b) -- 3
print(a % b)  -- 1
print(a ^ b)  -- 1000.0

/ 总是返回浮点数,// 执行向下取整除法。负数取模的结果符号与除数一致:

print(-7 // 3) -- -3
print(-7 % 3)  -- 2

位运算

Lua 5.4 支持按位或 |、按位与 &、按位异或 ~、左移 <<、右移 >> 和一元按位非 ~:

print(5 | 2)  -- 7
print(5 & 1)  -- 1
print(5 ~ 1)  -- 4
print(1 << 4) -- 16
print(~0)     -- -1

位运算会把浮点数转换为整数。转换失败会报错,因此来自外部输入的数字应先校验。

比较与逻辑运算

比较

print(1 == 1.0)  -- true
print("a" ~= "b") -- true
print(2 < 3)     -- true

不同类型通常不能使用大小比较。需要比较字符串时,Lua 按字节序比较:

print("apple" < "banana") -- true

逻辑运算

and、or 和 not 都基于真值规则:

print(0 and "yes")          -- yes
print(nil or "fallback")    -- fallback
print(false or 0)           -- 0
print(not nil)              -- true

注意 and 和 or 返回参与运算的值,而不是固定返回布尔值。因此可以写默认值:

local function greet(name)
  name = name or "访客"
  return "你好," .. name
end

但默认值写法对 false 和 nil 都会触发回退。如果业务允许 false,应显式判断:

local function withDefault(value, default)
  if value == nil then
    return default
  end
  return value
end

字符串连接与长度

使用 .. 连接字符串或数字:

local name = "Lua"
local version = 5.4

print(name .. " " .. version) -- Lua 5.4

大量连接字符串时,反复创建中间字符串会带来开销。可以把片段放进表,最后使用 table.concat:

local parts = {}
for i = 1, 5 do
  parts[#parts + 1] = "line-" .. i
end
print(table.concat(parts, "\n"))

# 返回字符串字节长度或表的边界长度。对含空洞的表使用 # 时结果不确定,应使用显式计数或遍历。

优先级与短路求值

Lua 常用优先级从高到低:

^
not  #  -  ~
*  /  //  %
+  -
..
<<  >>
&
~
|
<  >  <=  >=  ~=  ==
and
or

.. 是右结合的。and 和 or 具有短路行为:

local function expensive()
  print("不会执行")
  return true
end

local result = false and expensive()
print(result)

不要依赖复杂表达式的隐式优先级。对混合逻辑表达式使用括号,或用局部变量拆分步骤,可读性更高。

数字与字符串转换

算术运算会自动把数字字符串转换为数字:

print("10" + 2) -- 12

但显式转换更可靠:

local number = tonumber("10")
if number == nil then
  error("不是有效数字")
end

local text = tostring(10)
print(number + 5, text .. " items")

tonumber 可以接收进制参数:

print(tonumber("ff", 16)) -- 255
print(tonumber("2.5"))    -- 2.5
print(tonumber("abc"))     -- nil

处理用户输入时始终检查 tonumber 是否返回 nil,不要依赖自动转换。

上一章:基本类型与变量 | 下一章:控制流