在绝大多数情况下,我们都不会用到rawget和rawset。

本文的运行环境:lua 5.3 for windows

rawset 赋值操作

rawset是在设置值的过程,进行处理,比如:当某个值改变时,触发事件。或修改某个key为新值。

来看看rawset函数的定义

--- Sets the real value of `table[index]` to `value`, without invoking the
--- `__newindex` metamethod. `table` must be a table, `index` any value
--- different from **nil** and NaN, and `value` any Lua value.
---@param table table
---@param index any
---@param value any
function rawset(table, index, value) end

看个例子,设置过__newindex之后,就不会调用__index了?

local tb = {}
setmetatable(tb, { __index = function()
return "not find"
end })
setmetatable(tb, { __newindex = function(table, key, value)
local patchKey = "version"
if key == patchKey then
rawset(table, patchKey, "补丁值")
else
rawset(table, key, value)
end
end })
tb.version = "正常版本"
tb.date = "2018"
print(tb.version) --打印 补丁值
print(tb.server) --打印nil,不会调用__index方法了?
print(tb.date) --打印2018

经过我的测试后, 发现

---如果把__index放在__newindex之后,调用不存在值,才会调用__index方法
如果在__index在__newindex之前,则不会调用

rawget 取原始值

rawget是为了绕过__index而出现的,直接点,就是让__index方法的重写无效

来看看rawget函数的定义

--- Gets the real value of `table[index]`, the `__index` metamethod. `table`
--- must be a table; `index` may be any value.
---@param table table
---@param index any
---@return any
function rawget(table, index) end

编写一个例子,测试rawget绕过__index方法

local tb = {}
setmetatable(tb, { __index = function()
return "not find"
end }) tb.version = "正常版本"
print(tb.version)
print(tb.server) ---不存在的值,调用__index方法
--rawget是为了绕过__index而出现的,直接点,就是让__index方法的重写无效
print(rawget(tb, "version")) --打印 正常版本
print(rawget(tb, "server")) --打印nil

__newindex

__newindex可以和rawset配合使用,也可以单独使用

当为表分配值时,解释器会查找__newindex方法,如果存在,则解释器会调用它。

结合使用 __index和 __newindex,允许lua有强大的构造,从只读表,到具有默认值的表,到面向对象编程的继承

文档:https://www.lua.org/pil/13.4.2.html

Lua5.3 __index要通过setmetatable设置

在lua5.3中,直接使用tableA.__index = function() end 设置,我这边测试,并不会生效

local tempTable = { memberB = "test" }

tempTable.__index = function()
return "not find"
end print(tempTable.memberA) --打印 nil
print(tempTable.memberB) --打印test

而通过这种方式就正常

local tempTable = { memberB = "test" }
---__index定义了当key查找不到的行为
setmetatable(tempTable, { __index = function()
return "not find"
end }) print(tempTable.memberA) --打印 not find
print(tempTable.memberB) --打印test

Lua rawget rawset newindex 函数定义和例子的更多相关文章

  1. lua os.date函数定义和示例

    os.date函数定义 原型:os.date ([format [, time]]) 解释:返回一个按format格式化日期.时间的字串或表. lua源码中os.date的注释如下: --- --- ...

  2. lua函数定义

    FuncState proto结构数组保存函数原型信息;prev保存父函数体指针:actvar保存定义的局部变量:upvalues保存upvalue Lua源码中,专门有一个结构体FuncState用 ...

  3. Lua学习---函数定义

    1.函数定义的格式: Lua使用function定义函数,语法如下: function function_name (arc) --arc表示参数列表,函数的参数列表可以为空 --body end 上 ...

  4. lua如何调用C++函数

    第一步是定义函数.所有在Lua中被调用的C/C++函数将使用下面一类指针进行调用: typedef int (*lua_CFunction) (lua_State *L); 换句话说,函数必须要以Lu ...

  5. Lua中调用C函数

    Lua利用一个虚拟的堆栈来给C传递值或从C获取值.每当Lua调用C函数,都会获得一个新的堆栈,该堆栈初始包含所有的调用C函数所需要的参数值(Lua传给C函数的调用实参),并且C函数执行完毕后,会把返回 ...

  6. cocos2d-x 2.2.0 如何在lua中注册回调函数给C++

    cocos2d-x内部使用tolua进行lua绑定,但是引擎并没有提供一个通用的接口让我们可以把一个lua函数注册给C++层面的回调事件.翻看引擎的lua绑定代码,我们可以仿照引擎中的方法来做.值得吐 ...

  7. lua 11 闭包,函数的使用

    转自:http://book.luaer.cn/_41.htm 当一个函数内部嵌套另一个函数定义时,内部的函数体可以访问外部的函数的局部变量,这种特征我们称作词法定界.虽然这看起来很清楚,事实并非如此 ...

  8. lua学习之深入函数第二篇

    深入函数 2 非全局的函数 函数是第一类值,函数可以存储到全局变量,局部变量,table 字段中 lua 函数库中的大部分函数存储到 table 字段中 Lib = {} Lib.foo = func ...

  9. Matlab中函数定义方法

    Matlab自定义函数的六种方法 n1.函数文件+调用函数(命令)文件:需单独定义一个自定义函数的M文件: n2.函数文件+子函数:定义一个具有多个自定义函数的M文件: n3.Inline:无需M文件 ...

随机推荐

  1. vue 脚手架 立即可以写业务 vue + vue-router + less + axios + elementUI + moment

    https://github.com/cynthiawupore/wq-cli

  2. Android远程桌面助手(B1413)

    ARDC(B1413) 1.解决Android9显示黑屏问题;2.解决向导菜单显示异常问题;3.解决部分手机无法正常连接的问题;4.切换到WiFi连接时,增加显示NetworkID;5.更新图片压缩的 ...

  3. Oracle数据库升级注意事项

    1 备份配置参数 数据库升级前的配置参数要备份,如PGA大小 这样数据库升级后还可以升级前的配置,而不至于使用安装升级时的默认配置 2 检查版本兼容 确认数据库升级后是否对生产环境上的代码有影响,如果 ...

  4. SQL Server2008 xp_cmdshell啟用

    1. 查看系统数据库参数配置: select * from sys.configurations where name='xp_cmdshell' 修改系统数据库参数:   语法格式:     sp_ ...

  5. 第二周Python学习笔记

    分支结构: ①  单分支结构: 非常简单,if 条件语句,如果为true 则输出结果.否则不输出结果 ②  二分支结构: 条件结果为true则执行语句1,否则就执行语句2 If <条件>: ...

  6. Postman 安装

    前言 安装前的准备: 1.Chrome 浏览器的扩展插件来进行的安装,并非单独应用程序. 2.电脑上已经安装了 Chrome 浏览器 3.本文章适用操作系统  window7 一,非官方安装 个人不建 ...

  7. Windows系统配置OutLook邮箱教程一

    本示例演示Windows系统中OutLook邮箱设置 1.打开控制面板->类型选择小图标->找到Mail(Microsoft OutLook 2016). 2.鼠标左键双击Mail. 3. ...

  8. CAP 2.4版本发布,支持版本隔离特性

    前言 自从上次 CAP 2.3 版本发布 以来,已经过去了几个月的时间,这几个月比较忙,所以也没有怎么写博客,趁着2019年到来之际(现在应该是2019年开始的时候),CAP也发布了2018年的最后一 ...

  9. docker 备注

    1.docker 安装 #安装环境为centos yum -y install docker service docker start #测试是否安装成功,可执行命令 docker run hello ...

  10. Python中星号的本质和使用方式

    翻译:Python 开发者 - 一汀, 英文:Trey Hunner http://blog.jobbole.com/114655/ Python开发者 在 Python 中有很多地方可以看到*和** ...