Lua中的点、冒号与self
Lua中的点、冒号与self,它们之间的关系主要体现在函数的定义与调用上,Lua在函数定义时可以用点也可以用冒号,如:
function mytable.fun(p)
return p
end function mytable:fun(p)
return p
end
用冒号定义的函数有个特别的地方是它内部有个self表示自身可以直接访问(虽然self并不是Lua的关键字,他它确实是可以访问的),如同C++、C#的this:
myclass = {age = , name="aa"}
function myclass:fun(p)
print(self)
print(self.age)
print(p)
end
myclass:fun("")
输出:
table: 00D69810
可见self即myclass本身。如果上面不是冒号而是点则self不可用的会报错,因为self是个nil值。
点定义的函数可以以冒号的形式调用,冒号定义的函数也可以用点的形式来调用,两种方式都能成功调用到同一函数,但调用结果可能是错误的,上面代码最后一行的冒号改为点来调用:
myclass.fun("")
输出:
nil
nil
此时self不再是自身而是传入的参数“22”,而本身需要的参数p却是nil的。可见如果冒号定义的函数如果用点来调用时需要传入的参数个数自动增加一个,函数内部若有用到self则self表示的便是函数传入的第一个参数,第一个参数必须传入本身,否则最后函数执行结果会是错误的。上例正确的点调用应该是:
myclass.fun(myclass, "")
输出:
table: 00F298B0
我们反过来试一下,先来看:
function myclass.fun(p1, p2)
print(p1)
print(p2)
end myclass.fun("","")
输出:
这个很显然,如果调用改为冒号:
myclass:fun("","")
输出:
table: 00E39A90
第一个参数p1不是“22”却是一个table,第二个参数p2才是我们传入的第一个数“22”,可见冒号调用以点定义的函数时,函数的参数的意义发生了变化,第一个参数强制变为了表示自身的变量(此时的p1等同于self),如果函数原来的参数一的意义要求不是要调用者将本身调用传入则函数执行出错,因此这种情况下的点定义的函数并不能用冒号来调用,虽然也能调用到该函数但结果却是错的。
综上:
冒号定义成员函数相比点定义可以减少一个需要传入自身的参数,内部用self来访问自身;
点调用冒号定义的函数时,需要多传入一个参数,传入的第二个参数开始才对应于原函数的参数列表,函数内部用到的self则变为对应于传入的第一个参数的普通变量,故传入的第一个参数应该当是调用者自身(当然如果函数内部并没有用到self则第一个参数随便传个什么都行);
冒号调用点定义的函数时,原函数的第一个参数强制变为等同于self的变量,传入的参数从原参数的第二个参数开始才能一一对应上,因此通常这样调用都是会出错的(除非函数内部原本就把第一个参数在当self用...)。
故在Lua中成员函数的定义应该约定一种形式而不要点和冒号同时使用,不然调用者可能会不清楚该函数是否支持另一种方式的调用而增加出错的可能。
Lua中的点、冒号与self的更多相关文章
- lua 中的点、冒号与self
[lua 中的点.冒号与self] lua编程中,经常遇到函数的定义和调用,有时候用点号调用,有时候用冒号调用. girl = {money = 200} function girl.goToMark ...
- lua中的面向对象编程
简单说说Lua中的面向对象 Lua中的table就是一种对象,看以下一段简单的代码: 上述代码会输出tb1 ~= tb2.说明两个具有相同值得对象是两个不同的对象,同时在Lua中table是引用类型的 ...
- Lua中的一些库(1)
[数学库] 数学库(math)由一组标准的数学函数构成.这里主要介绍几个常用的函数,其它的大家可以自行百度解决. 三角函数(sin,cos,tan……)所有的三角函数都使用弧度单位,可以用函数deg( ...
- 理解lua中 . : self
前言 在LUA中,经常可以看到:. self,如果你学习过Java或C#语言,可以这样理解 .对于c#和java的静态方法 :相当于是实例方法 今天在CSDN上看到一篇博客写的很清楚,转载过来 原文出 ...
- Lua中“.”调用方法与“:”调用方法的区别
Lua中“.”调用方法与“:”调用方法的区别: ...
- 【转载】Lua中实现类的原理
原文地址 http://wuzhiwei.net/lua_make_class/ 不错,将metatable讲的很透彻,我终于懂了. --------------------------------- ...
- Unity3D热更新之LuaFramework篇[05]--Lua脚本调用c#以及如何在Lua中使用Dotween
在上一篇文章 Unity3D热更新之LuaFramework篇[04]--自定义UI监听方法 中,我对LuaBehaviour脚本进行了扩展,添加了两个新的UI监听方法,也提到最好能单写一个脚本处理此 ...
- Lua中的面向对象编程详解
简单说说Lua中的面向对象 Lua中的table就是一种对象,看以下一段简单的代码: 复制代码代码如下: local tb1 = {a = 1, b = 2}local tb2 = {a = 1, b ...
- lua中基类和“继承机制”
基类:基类定义了所有对于派生类来说普通的属性和方法,派生类从基类继承所需的属性和方法,且在派生类中增加新的属性和方法. 继承:继承是C++语言的一种重要机制,它允许在已定义的类的基础上产生新类. lu ...
随机推荐
- 《Java并发编程的艺术》留给自己以后看的笔记
<Java并发编程的艺术>这本书特别好,和<深入了解JAVA虚拟机>有一拼,建议做java的都看看,下面全部都是复制书中的部分内容,主要目的是做个笔记,方便以后遇到问题能找到. ...
- Data Structure Stack: Reverse a stack using recursion
http://www.geeksforgeeks.org/reverse-a-stack-using-recursion/ #include <iostream> #include < ...
- shiro1
基于角色的访问控制 RBAC(role based access control),基于角色的访问控制. 比如: 系统角色包括 :部门经理.总经理.(角色针对用户来划分) 系统代码中实现: //如果该 ...
- [原创]java WEB学习笔记11:HttpServlet(HttpServletRequest HttpServletRsponse) 以及关于 Servlet 小结
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
- 在webBrowser中取Cookie的方法
在很多情况下我们会使用间进程的webBrowser去实现一些网页的请求和抓去,这个时候有部分网页是取不到Cookie的,那怎么办呢?下面我提供一个方法,应该99%的都能取到, //取当前webBrow ...
- 大话设计模式--解释器模式 interpreter -- C++实现实例
1. 解释器模式: 给定一个语言,定义它的文法的一种表示 并 定义一个解释器,这个解释器使用该表示文法 来解释语言中的句子. 如果一种特定类型的问题发生的频率很高,那么可能就值得将该问题的各个实例表述 ...
- C++指向函数的指针
直接上代码: #include<iostream> #include<string> #include<vector> using namespace std; t ...
- .net短信接口调用示例(106短信通道)
1. [代码]调用代理示例 using System;using System.Data;using System.Configuration;using System.Collections;usi ...
- spring boot: 一般注入说明(四) Profile配置,Environment环境配置 @Profile注解
1.通过设定Environment的ActiveProfile来设置当前context所需要的环境配置,在开发中使用@Profile注解类或方法,达到不同情况下选择实例化不同的Bean. 2.使用jv ...
- 计算地球上两个坐标点(经度,纬度)之间距离sql函数
go --计算地球上两个坐标点(经度,纬度)之间距离sql函数 --作者:lordbaby --整理:www.aspbc.com CREATE FUNCTION [dbo].[fnGetDistanc ...