Lua中关于元方法的一些知识点小结_Lua

本篇要介绍的东西比较零散,都是一些小知识点,所以就放在一起了。

1.两个具有不同元表的值进行算术操作(比如加法)

之前举例的时候,两个table相加,这两个table都是具有相同的元表的,所以没有任何问题。
那么,如果两个table或者两个进行相加操作的值,具有不同的元表呢?

对于这种情况,Lua是这样处理:

a.如果第一个值有元表,就以这个元表为准
b.否则,如果第二个值有元表,就用第二个值的元表
c.如果两个值都没有元表,或者没有对于的元方法,那么,就会报错
 

2.关系类的元方法

除了加法减法这些算术类的操作之外,大于小于等这些关系类的操作也是有元方法的:
__eq:等于
__lt:小于
__le:小于等于
 
如果对两个具备不同元表的值进行这些比较操作,就会报错,一定要注意,这和加减法的规则不一样。
其实想想也很有道理,元表都不一样了,怎么去判断大小呢?判断大小是要有规则的。
 
比如,在军队里,中尉的职位肯定是小于上校的职位。
然后,到了外星世界呢(假设有外星人)?说不定中尉是大于上校的。
所以,地球人和外星人是不能用同一种方式进行军衔比较的。
 
当然,大家也许会说:那地球人和外星人也不能用同一种方式进行加法操作啊!
没错,但是,Lua就是这么规定的啊!你找作者去啊!关我什么事!
 
最后,比较特殊的,进行“等于”操作,是不会报错的,哪怕是具有不同元表的值进行等于操作。
其实这想想也是很有道理,地球人等于外星人吗?不等于。在外星那边,外星人也会得到一样的答案,即使判断标准不同。
(小若:Lua就是这么规定的,你还有道理个毛线啊!围绕着规则去说道理,很好玩吗?)
 

3.保护元表

我们都知道,通过setmetatable和getmetatable可以分别设置和获得元表。

但是,如果我们不希望元表被修改或者被看到呢?

比如某天你当了主程,你写了一个很牛的模块,因为某些原因要交给一个刚毕业不到30年的学生去修改。

(小若:毕业30年那还叫做学生吗?都快要退休了吧!)

你很肯定你的某个值的元表是不能被改动的,那,你就可以把它保护起来了。
 
我们可以给元表的__metatable字段赋值,比如:mt.__metatable = “你别碰它的元表,否则过了10年的试用期之后,你就等着走人吧!”

然后,如果那个毕业不到30年的学生真的不小心去修改你的元表的话:

复制代码 代码如下:

print(getmetatable(s1));
setmetatable(s1, mt);

将会输出类似以下的日志:
你别碰它的元表,否则过了10年的试用期之后,你就等着走人吧!
cannot change protected metatable
 
好了,这样这个学生就肯定不改你的元表了,毕竟工作要紧。(小若:试用期10年,真是个好公司)
 

4.结束

本来还想接着写下一篇的,毕竟时间还早,但是下一篇要介绍__index和__newindex。
我感觉我会说的比较多,还是明晚再写吧。

时间: 2024-10-24 11:37:02

Lua中关于元方法的一些知识点小结_Lua的相关文章

Lua元表与元方法实例讲解_Lua

Lua中提供的元表(metatable)与元方法(metamethod)是一种非常重要的语法,metatable主要用于做一些类似于C++重载操作符式的功能. Lua中提供的元表是用于帮助lua变量完成某些非预定义功能的个性化行为,如两个table的相加,通过让两者指向同一元表并修改该元表的元方法可以实现该功能. 任何table都可以成为任何值的元表,而一组相关的table也可以共享一个元表. 一些MetaMethod: 复制代码 代码如下: __add(a, b)               

lua元表和元方法 《lua程序设计》 13章 读书笔记

lua中每个值都有一个元表,talble和userdata可以有各自独立的元表,而其它类型的值则共享其类型所属的单一元表.lua在创建table时不会创建元表. t = {} print(getmetatable(t)) --显示过元表 此时是nil --可以用setmetatable来设置或修改任何table的元表 t1 = {} setmetatable(t,t1) assert(getmetatable(t) == t1) 任何table可以作为任何值的元表,而一组相关的table可以共享

Lua中执行系统命令方法介绍_Lua

Lua中,os.execute可以执行dos命令,但是返回的是系统状态码,默认输出. io.popen()也可以执行dos命令,但是返回一个文件.eg: 复制代码 代码如下: local t = io.popen('svn help') local a = t:read("*all") --a返回一个字符串,内容是svn help的内容 如果想执行某命令或程序可选os.execute(),如果还想捕捉该执行结果可用io.popen() eg:复制文件 复制代码 代码如下: os.exe

Lua中的一些常用函数库实例讲解_Lua

前言 这篇文章将会来一些比较轻松的内容,就是简单的介绍一下Lua中几个常用的库.简单的说就是几个API的介绍.所以说,看起来比较容易,也没有多大的分量.就是纯粹的总结.使用库就是为了方便我们的开发,提高开发效率,同时也能保证代码的质量.希望大家以后也不要重复造轮子了. 数学库 数学库(math)由一组标准的数学函数构成.这里主要介绍几个常用的函数,其它的大家可以自行百度解决. 三角函数(sin,cos,tan--) 所有的三角函数都使用弧度单位,可以用函数deg(角度)和rad(弧度)来转换角度

Lua中的模块与module函数详解_Lua

很快就要开始介绍Lua里的"面向对象"了,在此之前,我们先来了解一下Lua的模块. 1.编写一个简单的模块 Lua的模块是什么东西呢?通常我们可以理解为是一个table,这个table里有一些变量.一些函数- 等等,这不就是我们所熟悉的类吗? 没错,和类很像(实际上我说不出它们的区别).   我们来看看一个简单的模块,新建一个文件,命名为game.lua,代码如下: 复制代码 代码如下: game = {} function game.play()     print("那么

Lua中的捕获机制和转换技巧介绍_Lua

捕获 捕获是这样一种机制:可以使用模式串的一部分匹配目标串的一部分.将你想捕获的模式用圆括号括起来,就指定了一个捕获. 在string.find使用捕获的时候,函数会返回捕获的值作为额外的结果.这常被用来将一个目标串拆分成多个: 复制代码 代码如下: pair = "name = Anna" _, _, key, value = string.find(pair, "(%a+)%s*=%s*(%a+)") print(key, value)    --> na

Lua中的变量类型与语句学习总结_Lua

1. Lua类型 1.1 基本类型 Lua是一种动态类型语言,没有类型定义的语法.Lua一共有8种基础类型:nil(空).boolean(布尔).number(数字).string(字符串).userdata(自定义类型).function(函数).thread(线程).table(表). 函数type可根据一个值返回其类型名称(字符串),如print(type(print)),输出"function":print(type(type(X))) ,输出"string"

Lua中实现面向对象的一种漂亮解决方案_Lua

在 pil 中,lua 的作者推荐了一种方案来实现 OO,比较简洁,但是我依然觉得有些繁琐. 这里给出一种更漂亮一点的解决方案,见下文: 这里提供 Lua 中实现 OO 的一种方案: 复制代码 代码如下: local _class={}   function class(super)  local class_type={}  class_type.ctor=false  class_type.super=super  class_type.new=function(...)    local

Lua中的迭代器和泛型for学习总结_Lua

前言 迭代器就是一种可以遍历一种集合中所有元素的机制,在Lua中,通常将迭代器表示为函数.每调用一次函数,就返回集合中的"下一个"元素.每个迭代器都需要在每次成功调用之后保存一些状态,这样才能知道它所在的位置及如何走到下一个位置,通过之前博文的总结,闭包对于这样的任务提供了极佳的支持.现在我们就用代码来实现一个简单的迭代器. 复制代码 代码如下: function values(tb)      local i = 0      return function ()