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

Lua rawget rawset newindex 函数定义和例子

在绝大多数情况下,我们都不会用到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

转载于:https://www.cnblogs.com/zhaoqingqing/p/10032249.html

相关文章:

  • Python学习手册之正则表达式和元字符
  • 如何用纯 CSS 创作一个变色旋转动画
  • 【挥舞JS】JS实现继承,封装一个extends方法
  • 使用 Fastlane 实现 iOS 跟 Android 自动打包脚本
  • Python练习-迭代-2018.11.28
  • 武汉区块链软件技术公司:艺术市场如何从区块链中受益?
  • JAVA入门到精通-第26讲-异常
  • Elasticsearch实践(四):IK分词
  • Alpha 冲刺 (10/10)
  • 汉诺塔解析(图解)
  • Go 基础(非常基础)
  • 新海诚画集[秒速5センチメートル:樱花抄·春]
  • 微服务架构介绍及开源框架
  • 【345】机器学习入门 - 李宏毅机器学习笔记
  • 动态删边SPFA: [HNOI2014]道路堵塞
  • 【跃迁之路】【585天】程序员高效学习方法论探索系列(实验阶段342-2018.09.13)...
  • canvas绘制圆角头像
  • CSS 专业技巧
  • iOS编译提示和导航提示
  • JavaScript-Array类型
  • JavaScript学习总结——原型
  • JSDuck 与 AngularJS 融合技巧
  • Laravel 实践之路: 数据库迁移与数据填充
  • Python打包系统简单入门
  • spring + angular 实现导出excel
  • swift基础之_对象 实例方法 对象方法。
  • 短视频宝贝=慢?阿里巴巴工程师这样秒开短视频
  • 湖南卫视:中国白领因网络偷菜成当代最寂寞的人?
  • 蓝海存储开关机注意事项总结
  • 深度学习入门:10门免费线上课程推荐
  • Mac 上flink的安装与启动
  • ​水经微图Web1.5.0版即将上线
  • #大学#套接字
  • (31)对象的克隆
  • (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作...
  • (Redis使用系列) SpringBoot 中对应2.0.x版本的Redis配置 一
  • (翻译)Entity Framework技巧系列之七 - Tip 26 – 28
  • (附源码)springboot社区居家养老互助服务管理平台 毕业设计 062027
  • (一)SpringBoot3---尚硅谷总结
  • (一)基于IDEA的JAVA基础1
  • (转) ns2/nam与nam实现相关的文件
  • (转)Linux整合apache和tomcat构建Web服务器
  • .bat批处理出现中文乱码的情况
  • .NET Core 2.1路线图
  • .net 无限分类
  • .NET/ASP.NETMVC 深入剖析 Model元数据、HtmlHelper、自定义模板、模板的装饰者模式(二)...
  • .NET/C# 检测电脑上安装的 .NET Framework 的版本
  • .NET框架
  • @Conditional注解详解
  • @ModelAttribute 注解
  • []T 还是 []*T, 这是一个问题
  • [Angular] 笔记 9:list/detail 页面以及@Output
  • [AX]AX2012 R2 出差申请和支出报告
  • [AX]AX2012开发新特性-禁止表或者表字段
  • [BIZ] - 1.金融交易系统特点