当前位置: 首页 > news >正文

Lua-编译,执行和错误

目录

一、Lua的“编译”:把代码变成可执行的“函数”

1、dofile:简单但不灵活的“一键运行”

2、loadfile:更灵活的“编译后再执行”

3、loadstring:从“字符串”编译代码

4、三者的关系

二、编译的“坑”:作用域和性能

1.作用域问题(词法域VS全局编译)

2.“函数定义是赋值操作”的误解

三、更底层的 load 函数(了解即可)

四、错误处理:让程序更健壮

1、主动触发错误:error 函数

2、简化错误处理:assert 函数

3、补充细节


一、Lua的“编译”:把代码变成可执行的“函数”

Lua虽然是解释型语言,但它会把源代码预编译成中间形式(可以理解为“可执行的函数”),再执行。这部分核心是三个函数:dofile、loadfile、loadstring。

1、dofile:简单但不灵活的“一键运行”

作用:加载并运行一个Lua文件,相当于“打开文件->编译->执行”一步到位

实例:

dofile("test.lua")--直接运行test.lua中的代码

缺点:如果文件加载失败,会直接报错;并且每次调用都要重新编译,效率不高。

2、loadfile:更灵活的“编译后再执行”

作用:只编译文件,不直接执行,返回一个编译后的函数。用户可以决定什么时候执行这个函数。

实例:

local f = loadfile("test.lua") --编译该文件,返回一个函数
f();  --手动调用编译后的代码
f();  --可以多次调用,不用重复重复编译

优点:

编译一次,可以多次执行;

加载失败时会返回nil+错误信息,方遍自定义错误处理。

3、loadstring:从“字符串”编译代码

作用:和loadfile像似,但是他是从字符串中提取代码并运行,返回一个函数。

实例:

local f = loadstring("print("hello")") --把字符串里面的代码编译
f()  --编译执行分离
4、三者的关系

dofile就是loadfile的简易包装

function dofile(filename)local f = loadfile(filename)f()
end

二、编译的“坑”:作用域和性能

1.作用域问题(词法域VS全局编译)

loadfile编译代码时,不考虑“词法作用域”(即外层函数的局部变量),它编译的代码默认在全局环境中执行。

local i = 0
local f = loadstring("i = i + 1; print(i)")  -- 这里的 i 是全局的 i
local g = function() i = i + 1; print(i) end  -- 这里的 i 是外层的局部 if()  --> 1 (修改了全局 i)
g()  --> 2 (修改了外层的局部 i)
2.“函数定义是赋值操作”的误解

Lua中加载代码块(如loadfile加载包含函数定义的文件)时,函数定义的本质是“赋值操作”,需要手动执行编译后才能完成定义。

--foo.lua文件内容
function foo(x)print(x)
end--main.lua的内容
f = loadfile("foo.lua")
print(foo) -> nil 还未定义
f()
print(foo) -> function的地址,完成了定义
print(foo(999))-> 999 函数可以正常调用

三、更底层的 load 函数(了解即可)

loadfile 和 loadstring 都是基于 load 实现的。load 更灵活,它可以从 “自定义的读取器” 中获取代码(比如分块读取大文件),但平时用得少,知道即可。

四、错误处理:让程序更健壮

1、主动触发错误:error 函数

error 函数的作用是显式地在代码中抛出错误,中断程序执行并提示错误信息。

  • 语法:error(错误消息 [, 错误级别])
  • 示例(用户输入校验):

    lua

    print("enter a number:")
    n = io.read("*number")  -- 读取数字,若输入非数字则返回 nil
    if not n thenerror("invalid input")  -- 输入无效时,主动抛出错误
    end
    
    执行后,若输入非数字,程序会中断并提示 invalid input
2、简化错误处理:assert 函数

assert 是 Lua 内置的 “断言函数”,用于简化 “条件不满足则抛错” 的逻辑,相当于 if not 条件 then error(消息) end 的简写。

  • 语法:assert(条件, 错误消息)
    • 若 条件 为 true,返回 条件 的值;
    • 若 条件 为 false 或 nil,则抛出 错误消息
  • 示例(简化上面的输入校验):

    lua

    print("enter a number:")
    n = assert(io.read("*number"), "invalid input")
    
    效果和用 error 手动判断完全一致,但代码更简洁。
3、补充细节
  • 错误级别的控制error 可选第二个参数控制 “错误在调用栈中的层级”,一般用默认值(2)即可,不用额外关注。
  • 与元表的关联:文末注释提到 “这些操作可通过元表合法化”,比如对非 table 进行索引时,若元表定义了 __index,则不会直接报错(后续元表章节会详细讲)。
-- 捕获 loadstring 的错误
local f = assert(loadstring("i = i +", "语法错误的代码"))
-- 如果 loadstring 失败,assert 会抛出清晰的错误
http://www.dtcms.com/a/540343.html

相关文章:

  • Lua与LuaJIT的安装与使用
  • 数独生成题目lua脚本
  • 影响网站加载速度wordpress获得当前文章的相关文章
  • Hive 技术深度解析与 P7 数据分析架构师多行业全场景实战课程合集(视频教程)
  • 嘉兴高端网站建设公司网络安全等级保护
  • HOW - localstorage 超时管理方案
  • java如何判断上传文件的类型,不要用后缀名判断
  • 【Linux】系统备份与恢复:rsync 与 tar 的完整使用教程
  • ROS2系列(3):第一个C++节点
  • zookeeper是什么
  • 构建“全链路解决方案”:解决集团化医院信创的三重难题
  • 网站建设区别广安市邻水建设局网站
  • 网站中的文字滑动怎么做化妆品网站建设策略
  • 【Netty4核心原理⑮】【Netty 编解码的艺术】
  • PHP-Casbin 在分布式服务中利用 Watcher 做策略同步
  • OCP考试必须培训吗?费用多少?
  • SpringBoot + 百度内容安全实战:自定义注解 + AOP 实现统一内容审核(支持文本 / 图片 / 视频 + 白名单 + 动态开关)
  • 心智结构与组织学习
  • NAS 私有云零信任部署:cpolar 加密访问 + 本地存储,破解安全与便捷难题
  • C++面向对象继承全面解析:不能被继承的类、多继承、菱形虚拟继承与设计模式实践
  • 只做财经的网站厦门高端网站建设公
  • 星宿网站建设系统开发过程中原型有哪些作用
  • Angular 入门项目
  • 架构解析:衡石科技如何基于AI+Data Agent重构智能数据分析平台
  • 云栖实录:重构可观测 - 打造大模型驱动的云监控 2.0 与 AIOps 新范式
  • AR技术如何确保数据准确无误?
  • Python-openai对话LLM
  • 智慧码垛系统介绍
  • Axure高保真View Design框架元件库
  • 网站 linux 服务器昆明企业网站开发公司