全局变量的声明

简介: 全局变量的声明

Lua 语言中的全局变量不需要声明就可以使用。虽然这种行为对小型程序来说较为方便,但在大型程序中一个简单的手误就可能造成难以发现的 bug 。不过,如果我们乐意的话,也可以改变这种行为。由于 Lua 语言将全局变量存放在一个普通的表中,所以可以通过元表来发现访问不存在的全局变量的情况。


一种方法是简单地检测所有对全局表中不存在的键的访问:

setmetatable(_G, {
  __newindex = function (_, n)
    error("attempt to write to undeclared variable " .. n, 2)
  end,
  __index = function (_, n)
    error("attempt to read undeclared variable " .. n, 2)
  end
})


这段代码执行后,所有试图对不存在的全局变量的访问都将引发一个错误:

> print(a)
stdin:1: attempt to read undeclared variable a


但是,我们应该如何声明一个新的变量呢?方法之一就是使用函数 rawset ,它可以绕过元方法:

function declare (name, initval)
  rawset(_G, name, initval or false)
end


其中, orfalse 保证新变量一定会得到一个不为 nil 的值。


另外一种更简单的方法是把对新全局变量的赋值限制在仅能在函数中进行,而代码段外层的代码则被允许自由赋值。


要检查赋值是否在主代码段中必须用到调试库。调用函数 debug.getinfo(2, "S") 将返回一个表,其中的字段 what 表示调用元方法的函数是主代码段还是普通的 Lua 函数还是 C 函数。使用该函数,可以将 __newindex 元方法重写:

__newindex = function (t, n, v)
  local w = debug.getinfo(1, "S").what
  if w ~= "main" and w ~= "C" then
    error("attempt to write to undeclared variable " .. n, 2)
  end
  rawset(t, n, v)
end


这个新版本还可以接受来自 C 代码的赋值,因为一般 C 代码都知道自己究竟在做什么。


如果要测试一个变量是否存在,并不能简单地将它与 nil 比较。因为如果它为 nil ,那么访问就会引发一个错误。这时,应该使用 rawget 来绕过元方法:

if rawget(_G, var) == nil then
  -- 'var' 未被声明
  ...
end


正如前面所提到的,我们不允许值为 nil 的全局变量,因为值为 nil 的全局变量都会被自动地认为是未声明的。但是,要允许值为 nil 的全局变量也不难,只需要引入一个辅助表来保存已经声明变量的名称即可。一旦调用了元方法,元方法就会检查该表,看变量是否是未声明过的。最终的代码可能如下所示:

local declaredNames = {}
setmetatable(_G, {
  __newindex = function (t, n, v)
    if not declaredNames[n] then
      local w = debug.getinfo(2, "S").what
      if w ~= "main" and w ~= "C" then
        error("attempt to write to undeclared variable ".. n, 2)
      end
      declaredNames[n] = true
    end
    rawset(t, n, v)   -- 进行真正的赋值
  end,
  __index = function (_, n)
    if not declaredNames[n] then
      error("attempt to read undeclared variable "..n,2)
    else
      return nil
    end
  end
})


现在,即使像 x = nil 这样的赋值也能够声明全局变量了。


上述两种方法所导致的开销基本可以忽略不计。在第一种方法中,在普通操作期间元方法不会被调用。在第二种方法中,元方法只有当程序访问一个值为 nil 的变量时才会被调用。


Lua 语言发行版中包含一个 strict.lua 模块,它使用上述代码实现了对全局变量的检查。在编写 Lua 语言代码时使用它是一个良好的习惯。

目录
相关文章
|
8月前
|
人工智能 自然语言处理
AI、大模型如何重塑海外舆情监测行业
与此同时,以人工智能(AI)与大语言模型(LLM)为代表的新一代技术,正在深刻重塑舆情监测行业的核心逻辑。从过去依赖关键词和人工分析的监测体系,到如今多语言理解、深层情绪识别与传播趋势预测等高阶能力的构建,AI不仅极大提升了舆情监测的效率与精准度,也推动其从单一的危机应对工具,迈向企业战略制定的智能引擎。
440 0
|
人工智能 PyTorch 算法框架/工具
【AI系统】昇腾推理引擎 MindIE
本文详细介绍华为昇腾推理引擎 MindIE,涵盖其基本介绍、关键功能特性及三大组件:MindIE-Service、MindIE-Torch 和 MindIE-RT。文章深入探讨了各组件在服务化部署、大模型推理和推理运行时方面的功能和应用场景,旨在帮助读者全面了解 MindIE 如何支持 AI 业务的高效运行和模型的快速部署。
1398 0
|
存储 监控 IDE
5款冷门却超级好用的VS Code插件
VS Code的口碑越来越好,受欢迎度也越来越高,以我为例,有时一个项目中可能会用到C++、Java、JS等不同编程语言,如果针对每一种语言都去安装一款对应的IDE,那样不仅会浪费很多时间,而且会极大的拖慢电脑速度。而VS Code通过简单的配置,就可以让它与对应语言当下最为流行的IDE相提并论,因此,就没必要再去安装PyCharm、IDEA、Clion、Webstorm这些了。
5款冷门却超级好用的VS Code插件
|
存储 自然语言处理
非全局函数
非全局函数
145 0
|
存储 缓存 自然语言处理
小刚带你深入浅出理解Lua语言
前言这篇文章并不是针对某个知识点深入剖析,而是聚焦在Lua语言的关键知识点覆盖和关键使用问题列举描述。能够让学习者对Lua整体有个认识(使用一门新的语言不仅仅在用的时候适应它,而是知道怎么善于使用它),同时也可以作为一个工具文档在Lua中遇到具体问题的时候能从这里索引到相应的知识点和Lua的一些原理,得到启发。 1、Lua语言的特点简单的说Lua语言是一个可扩展的嵌入型的脚本语言。它具有以下的特点
小刚带你深入浅出理解Lua语言
|
存储 人工智能 分布式计算
|
7天前
|
人工智能 安全 API
CoPaw:5分钟部署你的 AI助理
源自阿里巴巴开源生态的个人 AI 助理——CoPaw。作为阿里倾力打造的开源力作,CoPaw 完美打通钉钉、飞书、Discord 等多平台对话通道,支持定时任务自动化。内置 PDF/Office 深度处理、新闻摘要等强大技能,更开放自定义扩展接口。坚持数据全程私有化部署,绝不上传云端,让每一位用户都能在大厂技术加持下,拥有安全、专属的智能助手。
|
10天前
|
人工智能 自然语言处理 JavaScript
2026年Windows+Ollama本地部署OpenClaw保姆级教程:本地AI Agent+阿里云上快速搭建
2026年OpenClaw凭借本地部署、私有化运行的特性,成为打造个人智能体的核心工具,而Ollama作为轻量级本地大模型管理工具,能让OpenClaw摆脱对云端大模型的依赖,实现**本地推理、数据不泄露、全流程私有化**的智能体验。本文基于Windows 11系统,从硬件环境准备、Ollama安装与模型定制、OpenClaw部署配置、技能扩展到常见问题排查,打造保姆级本地部署教程,同时补充阿里云OpenClaw(Clawdbot)快速部署步骤,兼顾本地私有化需求与云端7×24小时运行需求,文中所有代码命令均可直接复制执行,确保零基础用户也能快速搭建属于自己的本地智能体。
11409 97
|
8天前
|
人工智能 安全 JavaScript
阿里云上+本地部署OpenClaw(小龙虾)新手攻略:解锁10大必备Skills,零基础也能玩转AI助手
2026年,开源AI代理工具OpenClaw(昵称“小龙虾”)凭借“能实际做事”的核心优势,在GitHub斩获25万+星标,成为现象级AI工具。它最强大的魅力在于可扩展的Skills(技能包)系统——通过ClawHub插件市场的数百个技能,能让AI助手从简单聊天升级为处理办公、学习、日常事务的全能帮手。
7407 27
|
6天前
|
人工智能 JavaScript Ubuntu
5分钟上手龙虾AI!OpenClaw部署(阿里云+本地)+ 免费多模型配置保姆级教程(MiniMax、Claude、阿里云百炼)
OpenClaw(昵称“龙虾AI”)作为2026年热门的开源个人AI助手,由PSPDFKit创始人Peter Steinberger开发,核心优势在于“真正执行任务”——不仅能聊天互动,还能自动处理邮件、管理日程、订机票、写代码等,且所有数据本地处理,隐私完全可控。它支持接入MiniMax、Claude、GPT等多类大模型,兼容微信、Telegram、飞书等主流聊天工具,搭配100+可扩展技能,成为兼顾实用性与隐私性的AI工具首选。
5506 11

热门文章

最新文章