0Pricing
Lua Academy · 课时

泛型 for 和 break

将泛型 for 与 pairs/ipairs 结合使用,并通过 break 控制循环流程。

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

泛型 for 协议

Lua 的泛型 for 循环与迭代器函数配合使用。语法为 for vars in iter_func, state, init do。每次迭代时,Lua 调用 iter_func(state, lastVar),并将返回值赋给 vars。当第一个返回值为 nil 时,循环停止。

-- Manual use of next() iterator
local t = {a=1, b=2, c=3}
local key, val = next(t, nil)   -- first entry
while key ~= nil do
  print(key, val)
  key, val = next(t, key)       -- advance
end

使用 pairs() 遍历所有键

pairs(t) 返回一个迭代器,用于遍历表中的所有键值对,包括字符串键、整数键和混合类型的键。非整数键的遍历顺序未指定(哈希顺序)。数组部分和哈希部分都会被遍历。

local config = {
  host = "localhost",
  port = 8080,
  debug = true,
  [1] = "first",
}

for key, value in pairs(config) do
  print(key, value)
end
-- Prints all 4 entries in any order

使用 ipairs() 遍历数组键

ipairs(t) 从 1 开始遍历整数键,在遇到第一个 nil 值时停止。它安全、可预测,并且保持顺序。当顺序很重要且希望在第一个空缺处停止时,请对类似数组的表使用 ipairs。

local fruits = {"apple", "banana", "cherry"}

for i, fruit in ipairs(fruits) do
  print(i, fruit)
end
-- 1  apple
-- 2  banana
-- 3  cherry

-- stops at first nil
local t = {10, 20, nil, 40}
for i, v in ipairs(t) do
  print(i, v)  -- only 1,10 and 2,20
end

pairs 与 ipairs 的区别

请了解各自的适用场景:ipairs 用于有序的连续数组;pairs 用于字典或混合类型的表。ipairs 在第一个 nil 空缺处停止,而 pairs 会访问每个非 nil 键。对于纯数组,使用 ipairs 更符合惯用写法。

local mixed = {10, 20, key="val", 30}

-- ipairs only sees array part in order
print("ipairs:")
for i, v in ipairs(mixed) do
  print(i, v)  -- 1:10, 2:20, 3:30
end

-- pairs sees everything
print("pairs:")
for k, v in pairs(mixed) do
  print(k, v)  -- 1:10, 2:20, 3:30, key:val
end

使用闭包创建自定义迭代器

您可以将闭包作为自己的迭代器。工厂函数返回一个有状态的闭包,该闭包在每次调用时推进位置。当没有剩余内容可返回时,它会返回 nil,从而停止泛型 for 循环。

local function range(from, to, step)
  step = step or 1
  local i = from - step
  return function()
    i = i + step
    if i <= to then return i end
  end
end

for n in range(1, 10, 2) do
  io.write(n .. " ")
end
print()  -- 1 3 5 7 9

使用 string.gmatch 作为迭代器

string.gmatch(s, pattern) 返回一个迭代器,用于遍历字符串 s 中与模式匹配的所有内容。它通常用于拆分字符串、提取标记或查找模式的所有出现位置。

local sentence = "the quick brown fox"

for word in string.gmatch(sentence, "%a+") do
  print(word)
end
-- the
-- quick
-- brown
-- fox

泛型 for 中的 break

您可以使用 break 提前退出泛型 for 循环。这对于搜索很有用:一直遍历到找到匹配项,然后退出循环。退出后,执行会继续进行 end 之后的语句。

local inventory = {
  {name="sword", damage=50},
  {name="shield", armor=30},
  {name="bow", damage=35},
}

local target = "shield"
for i, item in ipairs(inventory) do
  if item.name == target then
    print("Found at index", i)
    break
  end
end

迭代期间修改表

使用 pairs() 迭代表时,绝不要插入或删除表中的键——其行为未定义(有些更改可能会被看到,有些则会被跳过)。如果需要修改表,请将更改收集到临时列表中,并在循环结束后应用。

local t = {a=1, b=2, c=3, d=4}
local toDelete = {}

-- Collect keys to delete
for k, v in pairs(t) do
  if v % 2 == 0 then
    toDelete[#toDelete+1] = k
  end
end

-- Delete after iteration
for _, k in ipairs(toDelete) do
  t[k] = nil
end
-- t = {a=1, c=3}

枚举模式

如果同时需要索引和值,请使用同时提供两者的 ipairs。如果只需要值而不关心索引,可以使用 _ 作为索引的惯用“无关”变量名。

local colors = {"red", "green", "blue"}

-- With index
for i, color in ipairs(colors) do
  print(i .. ": " .. color)
end

-- Ignore index with _
for _, color in ipairs(colors) do
  print(color)  -- just the values
end

直接使用 next()

next(t, key) 是底层的遍历函数。它返回 key 之后的下一个键值对;如果没有更多内容,则返回 nil。next(t, nil) 会返回第一个条目。您可以使用 next(t) ~= nil 检查表是否非空,这比计数更快。

local function isEmpty(t)
  return next(t) == nil
end

print(isEmpty({}))       -- true
print(isEmpty({1,2,3}))  -- false
print(isEmpty({a=1}))    -- false

快速检查

哪个迭代器会在表中的第一个 nil 空缺处停止?

回顾:泛型 for 与 break

总结:

  • pairs(t) —— 所有键,顺序任意
  • ipairs(t) —— 1..n 的整数键,按顺序遍历,在 nil 处停止
  • 自定义迭代器:返回一个在结束时返回 nil 的闭包
  • break 可以提前退出循环
  • 绝不要在 pairs 遍历过程中修改表;收集更改并在之后应用
  • next(t) == nil —— 快速检查表是否为空

常见问题解答

「泛型 for 和 break」课时是免费的吗?

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

「泛型 for 和 break」这节课中我会学到什么?

将泛型 for 与 pairs/ipairs 结合使用,并通过 break 控制循环流程。 你通过在浏览器中直接运行的动手代码来练习 Lua Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Lua Academy 需要有经验吗?

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

「泛型 for 和 break」课时需要多长时间?

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

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

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

此课程中的所有课时

  1. if、elseif 和 else 语句
  2. while 和 repeat-until 循环
  3. 数值 for 循环
  4. 泛型 for 和 break
← 返回 Lua Academy