0Pricing
Lua Academy · 课时

算术运算符和关系运算符

有效使用 +、-、*、/、//、%、^ 和比较运算符。

算术运算符和关系运算符 是 CoddyKit 上的免费 Lua Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Lua Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Lua Academy 课程共包含 4 节课。

算术运算符概览

Lua 提供了完整的算术运算符集合:+(加法)、-(减法)、*(乘法)、/(浮点除法)、//(向下取整除法)、%(取模)、^(幂运算)以及一元 -(取负)。在 Lua 5.3+ 中,理解每个运算符何时返回整数、何时返回浮点数至关重要。

print(10 + 3)   -- 13
print(10 - 3)   -- 7
print(10 * 3)   -- 30
print(10 / 3)   -- 3.3333...  (always float)
print(10 // 3)  -- 3          (floor division)
print(10 % 3)   -- 1          (modulo)
print(2 ^ 10)   -- 1024.0     (always float)
print(-5)       -- -5

整数除法与浮点除法

/ 运算符始终返回浮点数,即使两个整数相除的结果恰好是整数。向下取整除法运算符 // 只有在两个操作数都是整数时才返回整数;如果其中一个是浮点数,结果也是浮点数,但仍会向下取整。

^ 幂运算符始终会转换为浮点数,因此 2^3 得到的是 8.0,而不是 8。如有需要,请使用 math.tointeger() 转回整数。

print(6 / 2)        -- 3.0  (float!)
print(6 // 2)       -- 3    (integer)
print(6.0 // 2)     -- 3.0  (float floor)
print(7 // 2)       -- 3    (floor toward -inf)
print(-7 // 2)      -- -4   (floor, not truncate!)
print(2 ^ 3)        -- 8.0  (always float)

取模运算符

Lua 的 % 运算符定义为 a % b == a - floor(a/b) * b。这意味着它遵循除数的符号,而不是被除数的符号。这一点不同于 C/Java,在 C/Java 中,结果遵循被除数的符号。

取模运算符可用于循环取值、循环遍历数组以及实现环形缓冲区。一种常见用法是:i % n 会在 0 到 n-1 之间循环。

print(10 % 3)    --  1  (positive)
print(-10 % 3)   --  2  (sign of divisor!)
print(10 % -3)   -- -2  (sign of divisor)

-- Cycling 1..5 example
for i = 1, 8 do
  local idx = (i - 1) % 5 + 1
  io.write(idx .. " ")  -- 1 2 3 4 5 1 2 3
end

关系运算符

Lua 的关系运算符返回布尔值:==(相等)、~=(不相等)、<、>、<=、>=。请注意,Lua 使用 ~= 表示不等于,而大多数语言使用 !=。

使用 == 比较不同类型的值时,结果始终为 false——相等检查不会进行隐式类型转换。在 Lua 中,1 == "1" 的结果是 false。

print(3 == 3)    -- true
print(3 ~= 4)    -- true
print(3 < 4)     -- true
print(3 >= 3)    -- true

-- No cross-type equality coercion
print(1 == "1")  -- false
print(0 == false) -- false

-- Strings compare lexicographically
print("abc" < "abd")  -- true

逻辑运算符:and、or、not

Lua 的逻辑运算符是 and、or 和 not。与许多语言不同,and 和 or 不会返回布尔值,而是返回其中一个操作数。这使得默认值和条件赋值等惯用模式成为可能。

  • a and b:如果 a 为假值,则返回 a;否则返回 b
  • a or b:如果 a 为真值,则返回 a;否则返回 b
-- and/or return operands, not booleans
print(1 and 2)        -- 2
print(false and 2)    -- false
print(1 or 2)         -- 1
print(false or 2)     -- 2

-- Default value idiom
local name = nil
local display = name or "Anonymous"
print(display)        -- Anonymous

三元表达式惯用写法

Lua 没有三元运算符(?:),但您可以使用 and/or 模拟它。只要 value_if_true 不是 nil 或 false,condition and value_if_true or value_if_false 这一模式就能正常工作。

这是 Lua 中非常常见的惯用写法。请注意一个边界情况:如果真分支的值恰好是 false,此模式就会失效,此时应改用 if 语句。

local x = 10
-- Ternary idiom
local label = x > 5 and "big" or "small"
print(label)   -- big

-- Works for non-false truthy values
local age = 20
local status = age >= 18 and "adult" or "minor"
print(status)  -- adult

-- Edge case: true branch is false -> use if
local val = true and false or "fallback"
print(val)  -- fallback (wrong!)

运算符优先级

Lua 的运算符优先级从低到高依次为:or、and、比较运算符(< > <= >= == ~=)、|、~、&、移位运算符、..、+ -、* / // %、一元运算符(not # - ~)、^。^ 和 .. 运算符是右结合的;其他运算符都是左结合的。

-- Precedence examples
print(2 + 3 * 4)     -- 14  (not 20)
print(2 ^ 3 ^ 2)     -- 512 (right assoc: 2^(3^2) = 2^9)
print(not 1 == 1)    -- false (not (1) == 1 => false == 1)
print(not (1 == 1))  -- false

-- Use parens to be explicit
print((2 + 3) * 4)   -- 20

位运算符(Lua 5.3+)

Lua 5.3 新增了原生位运算符,它们作用于整数:&(AND)、|(OR)、~(作为二元运算符时表示 XOR,作为一元运算符时表示 NOT)、<<(左移)、>>(右移)。在没有库支持的情况下,Lua 5.1/5.2 不提供这些运算符。

位运算符要求操作数为整数。传入浮点数会导致运行时错误,除非该浮点数恰好表示一个整数。

-- Bitwise operators (Lua 5.3+)
print(0xFF & 0x0F)   -- 15  (AND)
print(0xF0 | 0x0F)   -- 255 (OR)
print(0xFF ~ 0x0F)   -- 240 (XOR)
print(~0)            -- -1  (bitwise NOT)
print(1 << 4)        -- 16  (left shift)
print(256 >> 4)      -- 16  (right shift)

字符串长度与拼接

# 运算符返回字符串的字节长度,.. 运算符则拼接两个字符串。对数字使用 .. 时,Lua 会自动将数字转换为字符串。不过,使用 + 混合不同类型时遵循强制转换规则——看起来像数字的字符串可以用于算术运算。

local s = "hello"
print(#s)            -- 5
print(s .. " world") -- hello world
print(1 .. 2)        -- 12  (number to string)

-- Length of table = array part length
local t = {10, 20, 30}
print(#t)   -- 3

-- Beware: # on tables with holes is undefined
local h = {1, nil, 3}
print(#h)   -- 1 or 3 (undefined behavior!)

运算符的常见错误

Lua 中有几类常见的运算符相关错误:忘记 / 始终返回浮点数;使用 != 而不是 ~=(语法错误);误以为 0 或 "" 是假值(它们是真值);以及当真分支可能为 false 时仍依赖 and/or。

请始终测试边界条件,尤其要注意负数整除的情况,因为 // 会向负无穷取整。

-- Common mistakes
-- 1. / is always float
local result = 10 / 2
print(math.type(result))  -- float, not integer!

-- 2. ~= not !=
-- if x != 5 then  -- SYNTAX ERROR!
if 3 ~= 5 then print("not equal") end

-- 3. 0 is truthy
if 0 then print("0 is truthy in Lua!") end

-- 4. Negative floor division
print(-7 // 2)  -- -4 (not -3!)

快速检查

在 Lua 中,-7 // 2 的结果是什么?

回顾:算术与关系运算符

本节要点:

  • / 始终返回浮点数;// 向负无穷取整
  • ^ 始终返回浮点数,并且是右结合的
  • ~= 是不等运算符(不是 !=)
  • and/or 返回操作数,而不是布尔值——这支持默认值惯用写法
  • 只有 nil 和 false 是假值——0 和 "" 是真值
  • 位运算符(& | ~ << >>)要求使用 Lua 5.3+ 的整数

下一节:类型强制转换和显式转换函数。

常见问题解答

「算术运算符和关系运算符」课时是免费的吗?

是的 — 「算术运算符和关系运算符」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Lua Academy 课程的其余内容,请升级到 CoddyKit PRO。 Lua Academy 课程共包含 4 节课。

「算术运算符和关系运算符」这节课中我会学到什么?

有效使用 +、-、*、/、//、%、^ 和比较运算符。 你通过在浏览器中直接运行的动手代码来练习 Lua Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Lua Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Lua Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「算术运算符和关系运算符」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Lua Academy 课中编写并运行代码吗?

能。每节 Lua Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. Lua 数据类型概览
  2. 在 Lua 中声明变量
  3. 算术运算符和关系运算符
  4. 类型强制转换和显式转换
← 返回 Lua Academy