Lua基本语法 (4)

本文介绍了Lua中的全局环境、模块创建以及面向对象的实现。讲解了如何使用_setmetatable保留原始_G,展示了单继承和多重继承的实现,并探讨了弱引用table在保护私密性方面的作用。
摘要由CSDN通过智能技术生成

       Lua全局环境

定义一个全局变量
gName ="我是全局变量";
用三种方式输出变量的值
print(gName);
print(_G["gName");
print(_G.gName);

2.保留原来的_G

-- gNane="我是全局变量"
只要在定义新的环境时,把_G作为一个字段放到新的table里,就可以调用原来的全局变量了。
-- setfenv(1,{g=_G})
-- g.print(gNane)
-- gNane="我是全局变量2"
-- g.print(gNane)
-- g.print(g.gNane)
运行结果:nil
我是全局变量2

我是全局变量

setfenv函数两个参数分别代表:
1).第一个参数可以是即将要改变环境的函数,也可以是一个数字。数字1代表当前函数,数字2代表调用当前函数的函数,后面以此类推。

2).第二个参数,新的全局环境table。

3.使用_index保留原来的_G

定义一个全局变量
gName: “我 是 老 变 量“ ;
-一一个table,即将成为新的环境
newG={};
setmetatable(newG,{_index= _G});
将当前全局环境重新设置为新的table
setfenv(1,newG); 
gName="我是新变量";
-- 输出值
print(gName);
print(_G.gName);
运行结果:nil
我是全局变量2
我是全局变量

                    Lua模块

1.一个简单的模块
--我们来看看一个简单的模块,新建一个文件命名为game.Iua,代码如下
game= {}
function game.play(
print("开始吧");
end
function game.quit()
print("结束了");
end
return game;
当我们使用的时候,需要用到我们前面讲过的require
game = require("game");

game.play();

2.最终解决方案

--我们来看看一个简单的模块,新建一个文件命名为game.Iua,代码如下
module("game",package.seeall)//module(...,package.seeall)
function play(  )
print("开始吧")
end
function quit(  )
print("结束了")

end

而package.sel参数的作用就是让原来的_G依然生效相当于调用了:setmetatable(M,{_index =_G});

当我们使用的时候,需要用到我们前面讲过的require
game = require("game");

game.play();

                                Lua面向对象的实现

定义类:

冒号的作用就是:定义函数时,给函数的添加隐藏的第一个参数self; 调用函数时默认把当前调用者作为第一个参数传递进去。

TSprite={x=0,y=0}
function TSprite:setPosition( x,y)
self.x=x
 self.y=y
end
local who = TSprite
TSprite=nil
who:setPosition(1,2)

print(who.x,who.y)运行结果:1   2

单继承:

Hero={attack=0}
function Hero:new( o )
o=o or {}
setmetatable(o,self)
self.__index=self
return o
end
function Hero:skill( addAttack)
         self.attack=self.attack+addAttack
return self.attack
end
oneHero=Hero:new({attack=100})
oneHero:skill(10)

print(oneHero:skill(10))运行结果  120

多重继承

function search( classes,key )
for i=1,#classes do
    local value = classes[i][key]
    if value ~= nil then
        return value
    end
end
end


function createClass( ... )
local parents = {...}
local num = #parents
local child = {}
if num == 1 then     --单继承
    setmetatable(child, {
      __index = parents[1]
        })
else                 --多继承
    setmetatable(child, {
        __index = function( table,key )
            return search(parents, key)
        end
        })
  end
return child
end


TSprite = {}      --精灵类
function TSprite:new( o )
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
function TSprite:hello(  )
print("hello")
end


TBullet = {}      --子弹类
function TBullet:new( o )
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
function TBullet:fire(  )
print("fire")
end


BulletSprite = createClass(TSprite,TBullet) --子弹精灵 继承上面两个类
function BulletSprite:new( o )
    o = o or {}
    setmetatable(o, self)
    self.__index = self
    return o
end
function BulletSprite:say(  )
print("i say")
end


local bSprite = BulletSprite:new({id = 2}) --实例化具体的对象
bSprite:hello()
bSprite:fire()
bSprite:say()
print(bSprite.id)


私密性

function createTSprite(  )
	local self = {name="myName"}
	local function myBus(  )
		print("myBus是我 的函数,你不能直接调用")
	end 
	local function myGame(  )
		print("myGame是我 的函数,你不能直接调用")
	end 
	local function hello()
		print("hello:")
		myBus()
	end 
	local function hi(  )
		myGame()
	end 
	local function setName( newName )
		self.name=newName
	end 
	local function getName( )
		return self.name
             end
             return{hello=hello,hi=hi,setName=setName,myBus=myBus,getName=getName}

end
local sp= createTSprite(  )
sp.hello()
sp.hi(  )
sp.myBus(  )
-- sp.setName("100")
print( sp.getName())
运行结果:
hello:
myBus是我 的函数,你不能直接调用
myGame是我 的函数,你不能直接调用
myBus是我 的函数,你不能直接调用
myName

弱引用table

对于弱引|用table,其实有三种形式:
1.key值弱引|用,也就是刚刚说到的情况,只要其他地方没有对key值3引|用,那么,table自身的这个字段也会被删除。设置方法:setmetatable(t,{_mode="k" });
2.value值弱引|用,情况类似,只要其他地方没有对value值引|用,那么,table的这个value所在的字段也会被删除。设置方法:setmetatable(t,{_mode=“v" });
3.key和value弱引|用,规则一样但是key和value都同时生效任意一个起作用时都会设置方法:setmetatable(t,{_mode=
"kv" });导致table的字段被删除。
当然,这里所说的被删除,是指在Lua执行垃圾回收的时候并不一定是立刻生效的。

t={}
setmetatable(t,{__mode="v"})
key1={name="key1"}
t[key1]=1
key1=nil

key2={name="key2"}
t[key2]=2
key2=nil
强制进行一次垃圾收集
collectgarbage();
for key ,value in pairs (t)   do
	print(key.name ..":" ..value)
end
key1:1
key2:2


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值