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 ...
随机推荐
- LeetCode:贪婪算法
LeetCode:贪婪算法 贪婪算法基础 我 717. 1-bit and 2-bit Characters class Solution { public boolean isOneBitChara ...
- 图片加载控件glide
基本用法 //(1)加载网络图片 tvGlide1.setText("(1)加载网络图片"); Glide.with(this).load("http://img1.im ...
- inline 元素的特性
http://www.maxdesign.com.au/articles/inline/ http://www.w3.org/TR/CSS2/visuren.html#inline-boxes htt ...
- Vue组件通信(传值)
先介绍一下什么是组件把: 创建组件的两种方式: 全局组件 // 组件就是vue的一个拓展实例 let component=Vue.extend({ data(){ return{ //与vue实例中的 ...
- 改进地图的vo类
现在的地图只是各帧特征点的集合.创建地图:局部,全局.局部:只相机位置附近的特征点,用来和当前帧匹配求解相机位置的.全局:不定位,回环检测和地图表达.重点或麻烦:维护局部地图的规模.为了实时,保证地图 ...
- Struts2的工作流程分析
Struts2的工作流程分析 Posted on 2011-02-22 09:32 概述 本章讲述Struts2的工作原理. 读者如果曾经学习过Struts1.x或者有过Struts1.x的开发经验, ...
- JAVA强制类型转换(转载+自己的感想) - stemon
JAVA强制类型转换(转载+自己的感想) - stemon 时间 2013-10-29 15:52:00 博客园-Java原文 http://www.cnblogs.com/stemon/p/33 ...
- codevs1997 守卫者的挑战
题目描述 Description 打开了黑魔法师Vani的大门,队员们在迷宫般的路上漫无目的地搜寻着关押applepi的监狱的所在地.突 然,眼前一道亮光闪过.“我,Nizem,是黑魔法圣殿的守卫者. ...
- long long 与 __int64
1.long long VC中不能用,codeblocks中 可以 #include<iostream> #include<stdio.h> using namespace s ...
- Unity3D连接WCF
Unity3D连接WCF: 一.最简单的案例 1.VS2015中: (1)建立WCF应用服务程序ForUnity: (2)将自动生成的IService1.cs与Service1.svc删除: (3 ...