lua学习01——基础

***************************************转载请注明出处:http://blog.csdn.net/lttree********************************************



学习lua啦~

首先,一把好的武器——sublime,

相关 安装配置 传送门—— >here<



本篇博文主要内容有:

> lua的基本类型

> lua的 table

> lua的 function




先来一段lua的介绍吧:

首先 lua 是一个脚本语言(何为脚本语言?——看下面注释①),lua由标准C编写而成,所以它与C的交互非常好,比较容易的进行互相的调用,也很容易在各个平台进行编译,最关键的是它非常的"轻",整个压缩包,也就200多K。

在游戏开发中,用lua就很方便,在发布一个游戏后,发现个大BUG,如果按编译型语言的方法,你就需要去重新编译打包,巴拉巴拉~,黄花菜都凉了,用lua就很方便,修改好,覆盖原来的,当你重新登陆时,就用已经改好的了。对用户对开发都很方便。

所以,一起来学lua吧~。~



1. lua的基本类型

- - -在lua中,有8种基本类型,分别是

· nil						空类型
· number					数字类型,不分int or float or double,双精度浮点
· string					字符串类型,无法具体的更改某个位置的字符,只能整块整块操作
· boolean					布尔类型(只有nil与false 为假,其他都为真)
· function					函数类型(☆第一类值☆),非常重要,后面会细讲
· table					表类型,也很重要后面会细讲
· userdata				<span style="white-space:pre">	</span>自定义类型
· thread					线程类型

我们可以用type来判断一个变量的类型:

-- 判断变量的类型
	
function judgeType( val )
	
	if type(val)=="number" then
		print("类型是 number")
	elseif type(val)=="nil" then
		print("类型是 nil")
	elseif type(val)=="string" then
		print("类型是 string")
	elseif type(val)=="function" then
		print("类型是 function")
	elseif type(val)=="boolean" then
		print("类型是 boolean")
	elseif type(val)=="table" then
		print("类型是 table")
	end

end

local myInt = 3
local myFloat = 4.375
local myStr = "Hello Lua!"
local myFunc = function ()	end
local myBoolean = true
local myNil = nil
local myTable = {}

print("myInt")
judgeType(myInt)

print("myFloat")
judgeType(myFloat)

print("myStr")
judgeType(myStr)

print("myFunc")
judgeType(myFunc)

print("myBoolean")
judgeType(myBoolean)

print("myNil")
judgeType(myNil)

print("myTable")
judgeType(myTable)

(PS:要记住文件名不要起中文的~(我折腾了半小时))

会输出:





2. lua 的 table

- - - table,上面也说到了 表类型,在lua中 table既不是值 也不是变量,而是 对象。

首先,看一下,最简单的 table:

t = {}

我们可以用 数字、字符串、变量 来索引内容,也可以随时动态的添加内容。

(但是,虽然我们可以用任意值作为table的索引,但是当table作为数组时,默认还是从1开始的。)

t = {}
t[1] = 3
t["haha"] = "heihei"
local x = "haha"

print(t[1])
print(t["haha"])
print(t[x])

3
heihei
heihei

而且,table 也体现了lua中的 一个很重要的一点,引用 而非 属于(也可以说 是动态性质),仅有一个版本,不会创造副本。

k = t
k[x] = "hello"
print(t.haha)

hello

这里 我用到了t.haha,table后跟着 .xxx 等同于 table["xxx"]

当我们 将 t 与 k 都置为nil时,lua垃圾回收机制才会将 这些内容 释放。

就是,我们创建一个table,就是在划分一个空间创建它,然后在 这块 与变量名间 做个引用关系,如果有复制,就一直加一些引用,而不是创造一个新的副本,最后就是 一个table 外面牵着很多引用,当所有的引用都断开,lua的回收机制就会收了它~




3. lua 的 function

lua中非常重要的一个东西 —— 第一类值

啥意思呢,它是一个函数,但是可以作为变量,可以当参数,可以当返回值,可以...

- - - 它的形式:

function 函数名( 参数列表 )
	函数体
end

函数声明可以是这两种形式:

function function_name( ... )
	-- body
end

local fun = function ( ... )
	-- body
end

我们一般用第一种,第一种是第二种的语法糖(注释2)

但是,这两种还是有所区别的,看看下面这种情况

function sum( n )
	if n < 0 then
		return 1
	else
		return sum(n-1)
	end
end

local ssum = function ( n )
	if n < 0 then
		return 1
	else
		return ssum(n-1)
	end
end

print(sum(4))
print(ssum(4))

但是,这两种样子还是有所区别的

第二种ssum在编译时会报错——视图调用一个空值 ssum

第一种写法: 声明一个函数sum,并开始定义,然后可以直接调用。

第二种写法: 声明一个函数(匿名函数),开始定义,这时候还没赋值给 ssum,所以ssum是空值,所以会报错。

还是那句话——function 是第一类值!!

  在函数的声明中,当参数只有一个,而且参数是 table类型或者string类型 的时候,它就可以省略掉括号,

print("hello lua!")  等价于  print "hello lua!"
fun({x=1,y=2})  等价于  fun {x=1,y=2}


- - -  函数的返回值,function支持 多重返回值,直接return就行

-- 函数的返回值
function add( val1 ,val2 )
	return val1,val2,val1+val2
end

local q1,q2,ans = add( 2, 3 )
print(q1.." + "..q2.." = "..ans)


但是,函数的多重返回值也有一些规则,有些时候,返回的一些数据会被扔掉,这主要取决于 函数的位置

-- 函数的多重返回值
function demo( )
	return 1, 2
end

local a, b, c = 0, 0, 0
a, b, c = demo(), 5
print(a.." "..b.." "..c)
-- 输出:1 5 nil

a, b, c = 0, 0, 0
a, b, c = 5, demo()
print(a.." "..b.." "..c)
-- 输出:5 1 2

a, b, c = 0, 0, 0
a, b, c = 5, (demo())
print(a.." "..b.." "..c)
-- 输出:5 1 nil

上面这个函数 demo返回2个值,但如果 它不位于最后,那就只取第一个返回值,剩下的就被丢掉了,就像第一个例子一样。如果位于最后,那就尽可能多的返回值(也就是有多少返回多少),就像第二个例子。但如果 函数外加上个括号,那就只取第一个返回值了。


- - - function的变长参数,像函数内传入的参数个数是可变的

-- 变长参数
function sum( ... )
	
	print( "length is :" .. select('#', ...) )
	
	local s = 0
	for i, v in ipairs{...} do
		s = s + v
	end
	return s

end

print( sum(1,2,3,4,5) )
print( sum(3,3,4) )

这里也用到了 select('#',...) 用来 查参数长度, ...可以拿来当做表达式来用。


- - - 函数闭包 问题

function Counter()
     local count = 0
     return function ()
          count = count + 1
          return count
     end
end

local c = Counter()

print( c() )     
print( c() )

local c2 = Counter()
print( c2() )
print( c() )
print( c2() )

这个例子,很古典= =。

当你 编译,之前两个 print,会输出 1 2

这就是典型的闭包,但,当你以为 闭包 是函数公用变量时,再看看 下面三个 print,输出:1 3 2

所以,闭包,并不仅仅的是让函数内的某个变量一直保存,感觉像静态变量一样。

而是,对于每一个 引用该函数的 变量,它就会有一个闭包。

这应该怎么去理解呢?

—— 答案就在 那一句 function是第一类值,你把它当做一个变量,然后分析一下作用域,就发现很容易去接受理解了。


- - - 非全局函数

因为 函数是第一类值,所以它可以在table中存在

-- 非全局函数
t = {}
t.add = function (x, y)	return x + y end
t.sub = function (x, y) return x - y end

local a, b = 3, 4
print(t.add(3,4))
print(t.sub(3,4))

还有其他写法:

t = {
	add = function (x, y)	return x + y end
	sub = function (x, y) 	return x - y end
}

t = {}
function t.add (x, y)
	return x + y
end
function t.sub (x, y)
	return x - y
end

把函数放到局部变量中,它就只能在特定的作用域发挥作用,这点对于我们编程来说是比较有用的。


- - - 尾调用

尾调用,就是类似于 goto函数的调用,就是一个函数的最后一个动作是调用另一个函数。

function f(x) 
	return g(x)
end

可以发现,当我们执行到 最后一个动作——调用g函数后,返回到 f函数,也没有什么事情可以做,所以,我们可以不返回到f函数。

要知道,这么开销下去,都是放在栈中,很可能导致栈溢出的。

会使用尾调用消除,就应该先看程序是怎么判断它是尾调用的:

-- 1
function f( x )
	g(x)
end

-- 2
function f( x )
	return g(x) + 1
end

-- 3
function f( x )
	return x or g(x)
end

-- 4
function f( x )
	return (g(x))
end

-- 5
function f( x )
	return x[i].foo(x[j]+a*b , i+j)
end

上面的这些,除了第5个,都不是尾调用,

先说第一个,和例子有些像,但是 f函数在 调用完g函数后,并不能立即返回,它还要负责将g函数返回的结果丢弃。

后面的,都要对g函数返回的结果进行处理 再返回。(其实第一个也是进行了处理)

所以,要想安心用这个功能,那就好好的return吧。




注释:

① 脚本语言:是为了缩短传统的 编写-编译-链接-运行 过程而创建的一种计算机语言,一个脚本语言通常是进行 解释而非编译。它的优势在于可以 快速开发,容易部署,不必耗时编译/打包,可以嵌入到别的语言中,利用其它语言的库,而且易学易用,可以实时生成和执行。

② 语法糖:在语言中添加某种语法,对功能没有什么影响,但是会便于程序员调用,增加代码可读性,减少出错机会。



***************************************转载请注明出处:http://blog.csdn.net/lttree********************************************

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值