Lua C API 中的 lua_rawseti 与 lua_rawgeti 介绍

原文地址:Lua C API 中的 lua_rawseti 与 lua_rawgeti 介绍

欢迎参观我的网站:无敌牛 -- 技术/著作/典籍/分享等

在 Lua 的 C API 中,lua_rawsetilua_rawgeti 是两个用于直接操作表中整数键的函数。它们不触发元表机制,执行的是"原始"的读写操作,常用于性能敏感或需要绕过元方法的场景。


一、函数原型

复制代码
void lua_rawseti (lua_State *L, int index, lua_Integer n);
void lua_rawgeti (lua_State *L, int index, lua_Integer n);
  • L:Lua 状态机。
  • index:栈中表的位置 (可以是正数、负数或伪索引如 LUA_REGISTRYINDEX)。
  • n整数键,通常从 1 开始(Lua 数组惯例),但也支持 0、负数或大整数。

二、功能说明

lua_rawseti(L, index, n)

  • 栈顶的值 赋给表的第 n 个位置:table[n] = value
  • 赋值后弹出栈顶的值
  • 不触发 __newindex

示例:

复制代码
lua_newtable(L);              // 创建表 → 栈顶
lua_pushstring(L, "hello");   // 压入值 → 栈顶是 "hello",表在 -2
lua_rawseti(L, -2, 1);        // table[1] = "hello",弹出 "hello"

lua_rawgeti(L, index, n)

  • 从表中取出第 n 个值,并压入栈顶
  • 不触发 __index

示例(接上一个例子):

复制代码
lua_rawgeti(L, -1, 1);        // 取 table[1],压入栈顶
const char* s = lua_tostring(L, -1);  // 得到 "hello",将 Lua 栈上的某个值转换为 C 风格的字符串(const char*)
lua_pop(L, 1);                // 清理栈顶,从 Lua 栈(Lua Stack)的顶部移除指定数量的元素。

三、关键特性

特性 说明
不触发元表 绕过 __index / __newindex,适合在元方法内部安全操作表
仅支持整数键 如需字符串或其他类型键,请使用 lua_rawget / lua_rawset
动态扩展表 即使键 n 原本不存在,也会自动创建,不会报错
性能略优 无元表查找开销,适合高频数组操作
常用注册表操作 配合 luaL_ref 使用,存取引用编号:lua_rawgeti(L, LUA_REGISTRYINDEX, ref)

四、典型使用场景

  1. __index / __newindex 元方法中操作表
    → 避免递归调用。
  2. 操作注册表中的引用
    luaL_ref 返回整数,用 lua_rawgeti 取回。
  3. 高效访问数组型数据结构
    → 如向量、列表、缓冲区等。
  4. 实现内部缓存或索引结构
    → 用整数 ID 快速存取,避免字符串查找。

五、注意事项

  • 栈操作要小心rawseti 会弹出栈顶值,rawgeti 会压入值 ------ 注意栈平衡。
  • 键从 1 开始是惯例 ,但非强制;n=0n=-1 也可用,但需明确意图。
  • 不要用于非表对象 :若 index 不指向表,会报类型错误。
  • 不适用于字符串键 :请用 lua_rawset / lua_rawget

六、对比其他函数

函数 触发元表? 键类型 用途
lua_gettable / lua_settable 任意 普通表访问
lua_rawget / lua_rawset 任意 绕过元表,任意键
lua_rawgeti / lua_rawseti 整数 绕过元表,数组访问,性能更优

七、总结

  • lua_rawgeti / lua_rawseti专为整数键设计的原始表操作函数
  • 它们安全、高效、稳定,是 Lua C API 中最常用的基础工具之一。
  • 无论目标键是否存在,操作都不会报错 ------ Lua 表会自动扩展。
  • 在元表操作、注册表管理、数组处理等场景中不可或缺。
相关推荐
平头哥AI10 分钟前
Day 01 | go run 跑通第一个 Go 程序,go build 留下一个能拷走的 exe
开发语言·后端·golang
葡萄城技术团队1 小时前
工业数据可视化:使用活字格 AIcoding + Three.js 构建轻量化三维设备监控大屏
开发语言·javascript·信息可视化
qiaosaifei1 小时前
JAVA老项目中有大量的类名_编译时报找不到符号错误
java·开发语言
聪明蛋子哟1 小时前
MCP协议深度落地:如何用Python/Java双语言实现统一的工具调用网关?
java·开发语言·python
是隼人1 小时前
buuctf-pwn [HarekazeCTF2019]baby_rop2(64位ret2libc)题解(学习过程持续更新)
c语言·学习·安全·pwn入门·ctf入门
一晌小贪欢1 小时前
python-第27天:Python面向对象详解
开发语言·python·数据可视化·面向对象·python办公
迪康Defender2 小时前
公用电脑责任追溯难?迪康端点安全一体化管理系统用户模式详解
java·运维·开发语言·网络·其他·安全
16月6日-晴2 小时前
Java面向对象——接口
java·开发语言
wuyk5553 小时前
107.FreeRTOS 链表深度解析:从原理到面试满分答案
c语言·开发语言·数据结构·stm32·单片机·链表·面试
geovindu3 小时前
CSharp: Wordcloud
开发语言·后端·c#·.net·.netcore·词云