关于 __newindex 中“Lua 不执行基本赋值操作” 在 2.4 中的含义
2021-1-29 6:32:36
收藏:0
阅读:115
评论:1
来自 https://www.lua.org/manual/5.3/manual.html 请查看 2.4 节中关于元方法操作 __newindex 的如下语句:
__newindex: 对表执行索引赋值操作 table[key] = value。和索引事件一样,如果表不是表或 key 不在表中,会产生这个事件。在 table 中查找元方法。
和索引一样,这个事件的元方法也可以是一个函数或一个表。如果是函数,会使用 table、key 和 value 作为参数进行调用。如果是一个表,Lua 会对这个表进行索引赋值,使用相同的 key 和 value。(这个赋值是普通赋值,不是原始赋值,因此可能会引发另一个元方法。)
只要有 __newindex 元方法,Lua 就不会执行基本赋值操作。(如果必要,元方法本身可以调用 rawset 进行赋值。)
因此我想请问一下下面这句话具体是什么意思:
“Lua 不执行基本赋值操作。(如果必要,元方法本身可以调用 rawset 进行赋值。)”
这是不是意味着,如果值为数值,即原语类型,它不会通过元方法事件被赋值给提供的表,而我们必须使用 rawget 或其他方式?这对我来说非常令人困惑和矛盾。
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?

我想给你展示一些例子来帮你搞清楚这个问题。
原始赋值的例子:
local test = {} test['x'] = 1 -- 等同于 rawset(test, 'x', 1) print(test['x']) -- 1 print(rawget(test,'x')) -- 1当表
test没有__newindex元方法时,原始赋值的代码test['x'] = 1等同于rawset(test, 'x', 1)。接着是
__newindex元方法的例子:local test = {} setmetatable(test, {__newindex = function(t,key,value) end}) test['x'] = 1 print(test['x']) -- nil print(rawget(test,'x')) -- nil赋值
test['x'] = 1将会调用__newindex函数。如果__newindex函数什么也不做,那就什么也不会发生,我们将得到test['x']的 nil 结果。如果
__newindex函数调用了rawset:local test = {} setmetatable(test, { __newindex = function(t,key,value) rawset(t,key,value) -- t:test key:'x' value:1 end}) test['x'] = 1 print(test['x']) -- 1 print(rawget(test,'x')) -- 1这个代码与第一个例子有相同的效果。所以手册上说:
那么问题就是,如何使用
__newindex? 它可以用来分离表中的旧索引和新索引。local test = {y = 1} local newtest = {} setmetatable(test, { __newindex = function(t,key,value) newtest[key] = value end, __index = newtest }) test["x"] = 1 print(test['x']) -- 1 print(test['y']) -- 1 print(rawget(test, 'x')) -- nil print(rawget(test, 'y')) -- 1旧索引 'x' 和新索引 'y' 都可以通过
test[key]访问,可以通过rawget(test, key)分离。