运算符 #

一、算术运算符 #

1.1 基本算术运算 #

lua
local a, b = 10, 3

-- 加法
print(a + b)   -- 13

-- 减法
print(a - b)   -- 7

-- 乘法
print(a * b)   -- 30

-- 除法
print(a / b)   -- 3.333...

-- 整除(Lua 5.3+)
print(a // b)  -- 3

-- 取余
print(a % b)   -- 1

-- 幂运算
print(a ^ b)   -- 1000.0

-- 负号
print(-a)      -- -10

1.2 整除与取余 #

lua
-- 整除:向下取整
print(10 // 3)   -- 3
print(-10 // 3)  -- -4(向下取整)
print(10 // -3)  -- -4

-- 取余:a % b = a - (a // b) * b
print(10 % 3)    -- 1
print(-10 % 3)   -- 2
print(10 % -3)   -- -2

-- 判断奇偶
local function is_even(n)
    return n % 2 == 0
end

-- 取最后一位数字
local function last_digit(n)
    return n % 10
end

1.3 幂运算 #

lua
-- 平方
print(2 ^ 2)    -- 4.0
print(10 ^ 2)   -- 100.0

-- 立方
print(2 ^ 3)    -- 8.0

-- 开方
print(16 ^ 0.5) -- 4.0
print(27 ^ (1/3))  -- 3.0

-- 科学计数法
print(1e10)     -- 10000000000.0
print(2.5e-3)   -- 0.0025

二、关系运算符 #

2.1 比较运算 #

lua
local a, b = 10, 20

-- 等于
print(a == b)   -- false
print(a == 10)  -- true

-- 不等于
print(a ~= b)   -- true
print(a ~= 10)  -- false

-- 小于
print(a < b)    -- true

-- 大于
print(a > b)    -- false

-- 小于等于
print(a <= b)   -- true

-- 大于等于
print(a >= b)   -- false

2.2 不同类型比较 #

lua
-- 不同类型比较结果总是 false
print(10 == "10")   -- false
print(0 == false)   -- false
print(nil == false) -- false

-- 数字比较(整数和浮点数可以比较)
print(10 == 10.0)   -- true

-- 字符串比较(字典序)
print("a" < "b")    -- true
print("abc" < "abd") -- true
print("a" < "A")    -- false(ASCII 码)

2.3 表比较 #

lua
-- 表比较的是引用,不是内容
local t1 = {1, 2, 3}
local t2 = {1, 2, 3}
local t3 = t1

print(t1 == t2)  -- false(不同对象)
print(t1 == t3)  -- true(同一对象)

-- 深度比较需要自己实现
local function deep_equal(a, b)
    if type(a) ~= type(b) then
        return false
    end
    if type(a) ~= "table" then
        return a == b
    end
    for k, v in pairs(a) do
        if not deep_equal(v, b[k]) then
            return false
        end
    end
    for k, v in pairs(b) do
        if not deep_equal(a[k], v) then
            return false
        end
    end
    return true
end

三、逻辑运算符 #

3.1 基本逻辑运算 #

lua
-- and:与运算
print(true and true)    -- true
print(true and false)   -- false
print(false and true)   -- false
print(false and false)  -- false

-- or:或运算
print(true or true)     -- true
print(true or false)    -- true
print(false or true)    -- true
print(false or false)   -- false

-- not:非运算
print(not true)         -- false
print(not false)        -- true
print(not nil)          -- true
print(not 0)            -- false

3.2 短路求值 #

lua
-- and 短路:第一个为假则返回第一个值
print(false and print("不执行"))  -- false
print(nil and "hello")           -- nil

-- or 短路:第一个为真则返回第一个值
print(true or print("不执行"))   -- true
print("hello" or "world")        -- hello

-- 利用短路求值
local function greet(name)
    name = name or "World"  -- 默认值
    print("Hello, " .. name)
end
greet()        -- Hello, World
greet("Lua")   -- Hello, Lua

3.3 实用技巧 #

lua
-- 默认值
local config = user_config or default_config

-- 三元运算模拟
local max = a > b and a or b

-- 安全访问
local value = obj and obj.field or nil

-- 链式默认值
local name = first_name or last_name or "Anonymous"

-- 条件赋值
local status = score >= 60 and "及格" or "不及格"

-- 多条件判断
local function get_grade(score)
    return score >= 90 and "A" or
           score >= 80 and "B" or
           score >= 70 and "C" or
           score >= 60 and "D" or
           "F"
end

3.4 注意事项 #

lua
-- and/or 返回的是操作数,不是布尔值
print(1 and 2)    -- 2
print(1 or 2)     -- 1
print(false or 2) -- 2

-- 当 a 为假时,a and b or c 可能有问题
local a = false
local b = false
local c = "default"
print(a and b or c)  -- default(正确)

-- 但如果 b 为假,结果会错误
local x = true
local y = false
local z = "default"
print(x and y or z)  -- default(期望是 y,但得到了 z)

-- 正确的三元运算
local function if_else(condition, true_val, false_val)
    if condition then
        return true_val
    else
        return false_val
    end
end

四、字符串连接运算符 #

4.1 基本连接 #

lua
-- 使用 .. 连接字符串
local s1 = "Hello" .. " " .. "World"
print(s1)  -- Hello World

-- 连接数字
local s2 = "数字:" .. 42
print(s2)  -- 数字:42

-- 连接多个值
local name = "Lua"
local version = 5.4
local s3 = name .. " " .. version
print(s3)  -- Lua 5.4

4.2 连接注意事项 #

lua
-- 数字自动转换为字符串
print("值:" .. 123)  -- 值:123

-- 布尔值需要显式转换
-- print("值:" .. true)  -- 错误!
print("值:" .. tostring(true))  -- 值:true

-- nil 需要显式转换
-- print("值:" .. nil)  -- 错误!
print("值:" .. tostring(nil))  -- 值:nil

-- 表需要自定义转换
local t = {1, 2, 3}
-- print("值:" .. t)  -- 错误!
print("值:" .. tostring(t))  -- 值:table: 0x...

4.3 高效连接 #

lua
-- 少量连接:使用 ..
local s = "a" .. "b" .. "c"

-- 大量连接:使用 table.concat
local parts = {}
for i = 1, 10000 do
    parts[i] = tostring(i)
end
local s = table.concat(parts, ",")  -- 高效

-- 多行连接
local s = "第一行\n" ..
          "第二行\n" ..
          "第三行"

五、长度运算符 #

5.1 字符串长度 #

lua
local s = "Hello"
print(#s)  -- 5

-- 中文字符串(UTF-8 编码,每个中文 3 字节)
local chinese = "你好"
print(#chinese)  -- 6

5.2 表长度 #

lua
-- 数组长度
local arr = {1, 2, 3, 4, 5}
print(#arr)  -- 5

-- 空表
print(#{})  -- 0

-- 稀疏数组(注意!)
local sparse = {1, 2, nil, 4}
print(#sparse)  -- 可能是 4 或 2(不确定)

-- 字典长度
local dict = {a = 1, b = 2, c = 3}
print(#dict)  -- 0(# 不适用于字典)

5.3 计算表元素数量 #

lua
-- 计算字典元素数量
local function table_count(t)
    local count = 0
    for _ in pairs(t) do
        count = count + 1
    end
    return count
end

local dict = {a = 1, b = 2, c = 3}
print(table_count(dict))  -- 3

六、运算符优先级 #

6.1 优先级表(从高到低) #

text
^                (幂运算,右结合)
not  #  -        (一元运算符)
*  /  //  %      (乘除类)
+  -             (加减类)
..               (连接,右结合)
<  >  <=  >=  ~=  ==  (比较运算符)
and              (逻辑与)
or               (逻辑或,右结合)

6.2 优先级示例 #

lua
-- 幂运算最高
print(2 ^ 3 ^ 2)  -- 512(= 2 ^ 9,右结合)

-- 一元运算符
print(-3 ^ 2)     -- -9(= -(3 ^ 2))

-- 乘除优先于加减
print(1 + 2 * 3)  -- 7

-- 比较运算符优先于逻辑运算符
print(true and 1 < 2)  -- true

-- and 优先于 or
print(true or false and false)  -- true
print((true or false) and false)  -- false

6.3 使用括号明确优先级 #

lua
-- 推荐使用括号明确意图
local result = (a + b) * c
local condition = (x > 0) and (y > 0)
local value = (a or b) and c

七、位运算符(Lua 5.3+) #

7.1 位运算函数 #

lua
-- 按位与
print(bit32.band(0xFF, 0x0F))  -- 15

-- 按位或
print(bit32.bor(0xF0, 0x0F))   -- 255

-- 按位异或
print(bit32.bxor(0xFF, 0x0F))  -- 240

-- 按位非
print(bit32.bnot(0x0F))        -- 4294967280

-- 左移
print(bit32.lshift(1, 4))      -- 16

-- 右移
print(bit32.rshift(16, 4))     -- 1

7.2 Lua 5.3+ 位运算符 #

lua
-- Lua 5.3+ 支持位运算符
local a, b = 0xFF, 0x0F

-- 按位与
print(a & b)   -- 15

-- 按位或
print(a | b)   -- 255

-- 按位异或
print(a ~ b)   -- 240

-- 按位非
print(~a)      -- -256

-- 左移
print(1 << 4)  -- 16

-- 右移
print(16 >> 4) -- 1

7.3 位运算应用 #

lua
-- 判断奇偶
local function is_odd(n)
    return n & 1 == 1
end

-- 交换两数
local function swap(a, b)
    a = a ~ b
    b = a ~ b
    a = a ~ b
    return a, b
end

-- 取第 n 位
local function get_bit(n, pos)
    return (n >> pos) & 1
end

-- 设置第 n 位
local function set_bit(n, pos)
    return n | (1 << pos)
end

-- 清除第 n 位
local function clear_bit(n, pos)
    return n & ~(1 << pos)
end

八、运算符重载 #

8.1 通过元表重载 #

lua
-- 创建支持加法的向量
local Vector = {}
Vector.__index = Vector

function Vector:new(x, y)
    return setmetatable({x = x, y = y}, self)
end

-- 重载加法
function Vector:__add(other)
    return Vector:new(self.x + other.x, self.y + other.y)
end

-- 重载减法
function Vector:__sub(other)
    return Vector:new(self.x - other.x, self.y - other.y)
end

-- 重载乘法
function Vector:__mul(scalar)
    return Vector:new(self.x * scalar, self.y * scalar)
end

-- 重载字符串转换
function Vector:__tostring()
    return string.format("(%d, %d)", self.x, self.y)
end

-- 使用
local v1 = Vector:new(1, 2)
local v2 = Vector:new(3, 4)
local v3 = v1 + v2
print(v3)      -- (4, 6)
print(v1 * 2)  -- (2, 4)

8.2 可重载的运算符 #

元方法 运算符
__add +
__sub -
__mul *
__div /
__mod %
__pow ^
__unm -(一元)
__concat
__len #
__eq ==
__lt <
__le <=

九、实用示例 #

9.1 范围判断 #

lua
-- 判断数字是否在范围内
local function in_range(value, min, max)
    return value >= min and value <= max
end

-- 使用
print(in_range(5, 1, 10))   -- true
print(in_range(15, 1, 10))  -- false

9.2 数值约束 #

lua
-- 约束数值在范围内
local function clamp(value, min, max)
    return math.max(min, math.min(max, value))
end

print(clamp(5, 0, 10))   -- 5
print(clamp(-5, 0, 10))  -- 0
print(clamp(15, 0, 10))  -- 10

9.3 安全除法 #

lua
-- 安全除法,避免除以零
local function safe_divide(a, b)
    return b ~= 0 and a / b or nil
end

print(safe_divide(10, 2))  -- 5.0
print(safe_divide(10, 0))  -- nil

十、总结 #

本章介绍了 Lua 的各种运算符:

  1. 算术运算符:+、-、*、/、//、%、^
  2. 关系运算符:==、~=、<、>、<=、>=
  3. 逻辑运算符:and、or、not
  4. 字符串连接:…
  5. 长度运算符:#
  6. 位运算符:&、|、~、<<、>>(Lua 5.3+)
  7. 运算符优先级:了解优先级,使用括号明确意图
  8. 运算符重载:通过元表实现自定义运算

掌握运算符是编写高效 Lua 代码的基础。下一章,我们将学习控制流语句。

最后更新:2026-03-27