Lua语法收录复习【持续收录】

news/2025/3/10 1:41:57/文章来源:https://www.cnblogs.com/chenxiayun/p/18749969

第一题: pairs和ipair的区别?
答:在 Lua 中,pairs 和 ipairs 都用于遍历表(table),但它们的遍历方式和适用场景有显著区别:
ipairs 的特点:

  • 仅遍历连续数字索引:从 1 开始,按顺序递增遍历,直到遇到第一个 nil 值停止。
  • 忽略非数字键和稀疏键:例如跳过字符串键或中间存在空洞的键
  • 有序且可预测:严格按 1, 2, 3... 的顺序遍历
local t = {"a", "b", c = "skip", [3] = "c", [5] = "e"}for i, v in ipairs(t) doprint(i, v)
end
-- 输出:
-- 1   a
-- 2   b
-- 3   c

pairs 的特点:

  • 遍历所有键值对:包括数字键、字符串键、稀疏键等。
  • 无序且不可预测:遍历顺序由表的哈希结构决定,可能每次运行结果不同。
  • 不跳过任何有效键:即使中间存在 nil,也会继续遍历其他存在的键。
local t = {"a", "b", c = "value", [5] = "e"}for k, v in pairs(t) doprint(k, v)
end
-- 可能的输出(顺序不固定):
-- 1    a
-- 2    b
-- 5    e
-- c    value

第二题:解释一下Lua的__index
答:在 Lua 中,__index 是元表(metatable)中的一个核心元方法(metamethod),用于定义当访问表中不存在的键(key)时的行为。它是实现 Lua 面向对象编程(OOP)、继承、默认值等特性的关键。

  • 当尝试从表(table)中读取一个不存在的键时,Lua 会检查该表的元表中是否有 __index 元方法。
  • 若存在 __index,Lua 会根据 __index 的定义去寻找替代值,而不是直接返回 nil

_index 可以是 函数 或 另一个表,具体行为如下:

  1. __index 是一个表(Table)
local parent = { value = 10 }
local child = {}-- 设置 child 的元表为 { __index = parent }
setmetatable(child, { __index = parent })print(child.value)  -- 输出 10(实际访问的是 parent.value)
  1. __index 是一个函数(Function)
local table_with_default = {}
setmetatable(table_with_default, {__index = function(t, key)return "默认值"end
})print(table_with_default.name) 

第三题:解释一下Lua的__newindex
答:在 Lua 中,__newindex 是元表(metatable)中的另一个核心元方法(metamethod),它控制当尝试向表中写入一个不存在键值时的行为。
当尝试向一个表写入一个不存在的键时,Lua 会检查该表的元表中是否有 __newindex 元方法:

  • 如果 __newindex 是函数,则调用该函数处理赋值。
  • 如果 __newindex 是另一个表,则实际写入该表。
  • 如果 __newindex 不存在,则直接在原表中创建新键值。
  1. __newindex 是函数
local t = {}
local proxy = {}  -- 代理表,用于记录操作setmetatable(t, {__newindex = function(raw_table, key, value)print("拦截写入:", key, "=", value)-- 将实际数据存储到 proxy 表中proxy[key] = valueend
})t.name = "Alice"  -- 输出:拦截写入: name = Alice
print(t.name)     -- 输出 nil(实际未写入 t,而是写入了 proxy)
print(proxy.name) -- 输出 Alice
  1. __newindex 是另一个表
local t = {}
local hidden = {}setmetatable(t, {__newindex = hidden  -- 写入不存在的键时,实际写入 hidden 表
})t.name = "Bob"
print(t.name)      -- 输出 nil(未写入 t)
print(hidden.name) -- 输出 Bob

第四题:介绍一下Lua的Module是什么
答:一个 Lua 模块本质上是一个返回表的 Lua 文件。这个表中包含了模块对外暴露的函数、变量或其他数据。当其他代码通过 require 加载模块时,会获得这个表,从而访问模块的功能。

module("mymodule", package.seeall)function add(a, b)return a + b
end
  1. Lua 会创建一个新表 mymodule,并将其赋值给全局变量 _G.mymodule。
  2. 设置当前模块的环境为 mymodule,即后续代码默认在 mymodule 表中定义变量和函数。
  3. package.seeall 让模块的环境继承 _G 的全局变量(通过元表 __index = _G)。

所以,add方法的完整路径是_G.mymodule.add。再强调下package.seeall的作用:package.seeall 允许模块代码读取全局变量(例如访问全局的 math、table 等),但不会将模块内的定义泄露到全局。模块内定义的变量和函数仍然属于模块自己的表。


第五题:介绍一下Lua的require方法
答:当调用require("module.name")时,Lua执行以下步骤:

  1. 检查缓存:查找package.loaded["module.name"],若已存在则直接返回。
  2. 查找文件:
    • 将模块名中的.转换为路径分隔符(如/)
    • 按package.path中的模式搜索Lua文件(如module/name.lua)。
    • 若无结果,按package.cpath搜索C模块(如module/name.so或name.dll)。
  3. 加载模块:
    • 对于Lua文件,执行文件并获取返回值。
    • 对于C模块,通过loadlib加载符号。
  4. 缓存结果:将模块返回值存入package.loaded["module.name"]
  5. 返回结果:若模块未返回值,默认返回true

对于 Lua 而言,每个 Lua 文件都需要通过 require 加载一次后才能被其他代码使用。


第六题:介绍下Lua的:语法糖
答:在 Lua 中,冒号 : 是专门为面向对象编程设计的一种语法糖,主要用于简化对象方法的定义和调用。它的核心作用是隐式传递 self 参数,使得代码更简洁。

  1. 定义方法时用冒号
-- 用 : 定义的方法会自动接收一个隐式的 self 参数,指向调用该方法的表(对象)本身。
-- 定义一个表(类似对象)
local obj = {value = 10
}-- 用冒号定义方法(自动添加 self)
function obj:printValue()print(self.value) -- 通过 self 访问对象的属性
end-- 等价于
function obj.printValue(self)print(self.value)
end
  1. 调用方法时用冒号
-- 用 : 调用方法时,会自动将调用者作为 self 参数传入。
obj:printValue()  -- 输出 10(隐式传递 obj 作为 self)-- 等价于用 . 显式传递 self:
obj.printValue(obj)  -- 显式传递 obj 作为 self

第七题:介绍一下Lua的rawget
答:在 Lua 中,rawget 是一个用于直接访问表的原始字段的函数,它会绕过元表(metatable)的 __index 元方法。这意味着无论表是否有元表,rawget 都只会访问表中实际存储的键值对,而不会触发任何元方法的逻辑。

local t = {}
local mt = {__index = function(table, key)return "Default Value"end
}
setmetatable(t, mt)-- 普通访问:触发 __index 元方法
print(t.foo)  -- 输出 "Default Value"-- 使用 rawget:绕过元表,直接访问表的字段
print(rawget(t, "foo"))  -- 输出 nil(因为 t.foo 不存在)

第八题:介绍一下Lua的__call
答:Lua 中的 __call 元方法允许将一个表或用户数据(userdata)像函数一样调用。
当尝试调用一个 table 时(例如 my_table()),Lua 会执行以下操作:

  1. 检查该 table 的元表(metatable)是否定义了 __call 元方法。
  2. 如果定义了 __call,则调用该元方法,并将 table 本身作为第一个参数,后续参数为调用时的参数。
  3. 如果未定义 __call,直接调用会抛出错误:attempt to call a table value。
-- 定义一个 table 和元表
local my_table = {}
local mt = {__call = function(table_arg, ...)  -- __call 方法的第一个参数是 table 自身print("调用了 table!参数为:", ...)return "返回值"end
}-- 为 table 设置元表
setmetatable(my_table, mt)-- 调用 table,像函数一样使用
local result = my_table(1, "hello", true)
-- 输出:
-- 调用了 table!参数为: 1 hello true
print(result)  -- 输出: 返回值

第九题:介绍一下lua的table.move
答:将 sourcestartend 的元素复制到 target_tabletarget_indextarget_index + (end - start) 位置。

table.move(source, start, end, target_index [, target_table])

参数 target_table 可选,不选的话默认与 source 相同。若指定,元素将复制到此表。仅复制元素引用(如嵌套表,不深拷贝)。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/896185.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VS2022开发跨平台程序(ubuntu x64/aarch64)

1、目标平台安装编译环境sudo apt install openssh-server g++ gcc gdb gdbserver -y目标平台安装ninjiasudo apt install ninja-build目标平台安装较新版本的cmake ,否则VS提示目标平台版本太旧,不支持远程编译。 2、VS创建CMake项目,会有个默认打印Hello CMake的程序。 指…

软件工程作业2

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/SoftwareEngineeringClassof2023这个作业要求在哪里 https://www.cnblogs.com/huanghi4833/p/18760121这个作业的目标 掌握 GitHub 、Git 的基本使用方法, 积累个人编程项目的经验一、PSP表格PSP2.1 Personal Softw…

How Far Can We Go with Practical Function-Level Program Repair? 论文笔记

介绍 (1) 背景现有的很多基于 LLM 的 APR 方法针对的是 single-line 或者代 hunk-level 的程序修复,但它们通常依靠语句级别的故障定位技术。然而,人们普遍认为,准确识别陈述级的断层基本上可能是代价高昂的,即要求细粒度的输入或强有力的假设,从而有可能限制它们的适用性…

Ubuntu安装最新版本的cmake

1、下载地址 Index of /files/LatestRelease ,目前最新的是3.31.6 或者命令行方式下载wget https://cmake.org/files/LatestRelease/cmake-3.31.6-linux-x86_64.tar.gz2、解压tar -zxvf cmake-3.31.6-linux-x86_64.tar.gz3、替换已有的cmake,mv命令必须目标路径为空,所以使用…

[AI/GPT] Anything-LLM : (MIT)

概述: Anything LLM 简述一体式桌面和Docker AI应用程序,内置RAG、AI代理、无代码代理构建器等。urlhttps://anythingllm.com https://github.com/Mintplex-Labs/anything-llm20250220 : 3.7k fork / 38.1K star创建公司:Mintplex Labs Inc.创立时间:2023年12月(首次公开)…

再次认识java反射

一、概述 在认识java反射之前我们先来认识一下什么是动态语言与静态语言。 动态语言 是一类在运行时可以改变其结构的语言:例如新的函数、对象、甚至代码可以 被引进,已有的函数可以被删除或是其他结构上的变化。通俗点说就是在运行时代码可以根据某些条件改变自身结构。 主要…

【问题】HashMap的computeIfAbsent方法丢失数据问题分析

问题背景 前段时间碰到客户问题发现是 ConcurrentHashMap的computeIfAbsent导致死循环(ConcurrentHashMap死循环问题分析)就很好奇HashMap的computeIfAbsent会不会也有问题,一试之下发现确实存在问题,相同的代码在HashMap中会丢失插入的数据。 发生原因 【循环添加】时,如…

CFA学习

定量分析 利率 利率的定义:被认为是 ① 平衡借贷双方的平衡点(equilibrium interest rates)② 贴现率(货币的时间价值)③ 机会成本 利率的组成:通货膨胀➕各种风险 计算【现值/终值】用时间轴确实一目了然! # 经济学 # 财务报表分析 # 公司理财 # 投资组合管理 # 权益投…

INFINI Labs 产品更新 | Easysearch 增加异步搜索等新特性

INFINI Labs 产品更新发布!此次更新,Easysearch 增加了新的功能和数据类型,包括 wildcard 数据类型、Point in time 搜索 API、异步搜索 API、数值和日期字段的 doc-values 搜索支持,Console 新增了日志查询功能。 INFINI Easysearch v1.11.0 INFINI Easysearch 是一个分布…

语法trick

for (int i = 1; i <= n; ++i) {cout << dist[i] << " \n"[i == n];}

百万架构师第四十七课:并发编程的原理(二)|JavaGuide

原文链接 JavaGuide《并发编程的艺术》 并发编程的实现原理 目标上节课内容回顾 synchronized 原理分析 wait 和 notify Lock 同步锁回顾原子性 可见性 有序性JMM ​ JMM 是 JAVA 里边定义的内存模型。定义了多线程和我们内存交互的规范。屏蔽了硬件和操作系统访问内存的差异。…

[极客大挑战 2019]Havefun 1

进网站显示一只猫,于是看源代码 发现下面有注释<!--$cat=$_GET[cat];echo $cat;if($cat==dog){echo Syc{cat_cat_cat_cat};}-->所以在后面加上/index.php?cat=dog即可(小猫可爱捏)