公司有个项目涉及到网络通信,用到了websocket协议。其中和底层设备的通信模块用C++来做的,并且用到lua来做C++的扩展。之前用的最多就是PHP和javascript。突然用lua来做东西好多不习惯,不过上手之后觉得也挺好。lua小巧简洁,使用起来很灵活。
Lua是一个被设计成用于扩展C/C++编程的轻量级脚本语言,它的目标是成为一个很容易嵌入其它语言中使用的语言。Lua让C/C++编写的代码调用Lua脚本,同时C/C++函数也能够在Lua脚本中调用。与C/C++代码的交互性,让Lua在应用程序开发中有着广泛的应用基础。很多应用程序使用Lua作为自己的嵌入式脚本语言,以此来实现可配置性、可扩展性。
由于lua定位于一个很容易嵌入其它语言中使用的语言,不适合作为开发独立应用程序的语言。所以它只包括一个精简的核心和最基本的库,有一些最基本的内置函数来应对开发需要。要实现一些较为复杂或是比较具体的功能,则需要我们自己写代码来完成。以下我开发中遇到的一些问题,在此记录以备学习之用。
1.关于日期的
已知某一日期,比如“2014-12-04”,想要取得前一天日期,即”2014-12-03“。当然,举一反三或是取向前固定时间的日期或是向后固定时间的日期。
如果是PHP来做的话,相对要简单。
PHP代码:
$date = "2014-12-04"; $pre_date = date("Y-m-d", strtotime($date) - 60*60*24); echo $pre_date;
用lua实现的话还是同样的思路,获取当前日期的时间戳,减去一天时间的秒数(60*60*24)。再用相应的日期函数来定义要获得的日期格式。但是lua要相对麻烦一点。lua最常用的关于日期和时间的函数是os.date()和os.time()。
os.date ([format [, timestamp]]),第一个参数format用于定义返回的日期时间格式,第二个参数timestamp为时间戳。两个参数都可以省略,默认返回当前的日期时间,如“12/04/14 21:56:35”。
os.time([table]), os.time()函数的参数类型是table(这是lua中的常用的数据类型,这里不做展开),该函数按table的内容返回一个对应的时间值(数字),若不带参数则返回时间戳。即返回的是参数中定义的时间点到1970 年 1 月 1 日 00:00:00(Unix 纪元)的秒数。如os.time({year=2014, month=12, day=04, hour=0, min=0, sec=0})返回的是2014-12-04 00:00:00到1970-01-01 00:00:00的秒数,值为1417622400。
对了两个函数有一定了解,就可以实现了。先对字符串“2014-12-04”截取分别获得年、月、日的值。然后通过os.time()获取“2014-12-04”的时间戳,再减去一天的秒数。最后再用os.date()格式化得到需要的日期格式。
lua代码:
local date = "2014-12-04" local year = string.sub(date, 1, 4) local month = string.sub(date, 6, 7) local day = string.sub(date, 9, 10) local pre_date = os.date("%Y-%m-%d", os.time({year = year, month = month, day = day}) - 60*60*24) print(pre_date)
以上。
要获取向前固定时间的日期或是向后固定时间的日期修改 -60*60*24处即可。
2.关于比较运算
这里主要讨论lua中的相等比较运算“==”。lua中的相等比较(==)是判断两个数据的类型和内容是否都相同,而PHP的相等比较(==)则只对比两个数据的内容是否相同,类型是否相同则不考虑。若要同时判断类型和内容是否相同,用的比较运算符是"==="(三个等号)。
PHP代码:
$string = "34"; $number = 34; if($string == $number){ echo "match"; }else{ echo "no match"; } //输出match echo "<br>"; if($string === $number){ echo "match"; }else{ echo "no match"; } //输出no match
lua代码:
local str = "34" local num = 34 if str == num then print("match") else print("no match") end --输出 no match
可见PHP和lua中关于比较运算的不同,要特别注意,不要想当然。
lua中的os.date()函数返回的就是字符串类型的值。之前我用os.date(“%H”)获取当前时间的小时和数字匹配比较,如 if os.date("%H") == 9 then 就会始终匹配不上。应为 if os.date("%H") == "9" then才有可能匹配上。特此说明,愿为他人之鉴。
3.关于table(关系表)拆分
lua中的table是一种特殊的数据类型,叫做关系表类型,我们可以把这个类型看作是一个数组。在lua中可以用除了nil以为的任意类型来作为关系表索引和和关系表内容。
在lua中定义表的方法很简单
local tab = {} tab[1] = 11 tab["second"] = 12 tab.three = 13 print(tab[1], tab.second, tab.three) --输出 11 12 13
以上代码首先定义了一个空表,当然可以在定义时让表就有内容,如 local tab = { 2, "test"}。然后给空表添加了三个元素。索引值是字符串时,可以用tab.second这种方式获取到。如果不写索引,则索引就会被认为是数字,索引值自1开始加1递增。如local tab = { 2, "test"},可以通过tab[1]和tab[2]获取到2和"test"。
关于lua的table用法简单介绍这些。
我在开发时用到udp协议发送数据,但发送数据有大小限制。最终确定要将发送内容中的一部分字符串分包发送,而这部分字符串时通过一个关系表得到。所以要将这个表拆分为多个表,然后在多次转换获取字符串分别发送。这个表的索引都是数字,从1开始编号的。
如果用PHP做这个东西的话,则相对简单。
PHP代码:
$arr = array(); for($i = 0; $i < 300; $i ++){ $arr[] = $i; } $new_arr = array_chunk($arr, 50); echo '<pre>'; print_r($new_arr); echo '<pre>';
PHP已内置了array_chunk()函数,足以满足以上所说的需求,并且不要求数组索引值必须为数字。关于array_chunk(array,size,preserve_key)的详细用法,读者可以到PHP手册中详细了解,在此不再赘述。
那么lua如何实现呢,先看代码,lua代码:
local tab = {} local newTab = {} local offset = 70 for i=1, 300 do tab[i] = i end local count = math.ceil(#tab/offset) for i=1, count do newTab[i] = {} end for k, v in pairs(tab) do table.insert(newTab[math.ceil(k/offset)], v) end --[[ newTab = { [1] = {1, 2, 3, ..., 70} [2] = {71, 72, 73, ..., 140} [3] = {141, 142, 143, ..., 210} [4] = {211, 212, 213, ..., 280} [5] = {281, 282, 283, ..., 300} } ]]--
tab是已知的关系表,newTab是要得到的关系表,offset是tab拆分后小关系表的长度,即所包含元素个数。首先初始化tab为一个包含300个元素的关系表,索引值从1到300。现在要得到newTab为代码最后注释部分内容。
然后,local count = math.ceil(#tab/offset)。#tab获取关系表tab中元素个数,另一种方法为table.getn(tab)。注意这两种方法只能正确获取关系表中索引从1开始的,连续递增的元素的个数。使用时要慎重。math.ceil()是lua中的向上取整,相关的math.floor()是向下取整。ceil是天花板,而floor是地板的意思。很形象,PHP中也有这两个函数。math.ceil(#tab/offset)是的道newTab中的元素个数。初始化好newTab。
最后遍历tab表,按照条件将数据插入到新表newTab中。newTab[math.ceil(k/offset)]的类型是表,之前已经定义。math.ceil(k/offset)是索引值,在这里值可能为1~5。table.insert(newTab[math.ceil(k/offset)], v)函数将v值插入到表newTab[math.ceil(k/offset)]中。这样newTab的就是要获取的表内容了。代码最后注释部分即为所得到的表结构。
以上就是我在用lua开发时候遇到的一些小问题,和PHP做了相关比较。PHP在一些具体的功能应用上都做了封装,使用起来比较简单,不用自己去定义实现。而lua则更基础灵活,运行速度会更快。各有利弊吧。
初次使用lua做东西,算是初窥门径。以上有表述不准确和不正确的地方,请大家斧正。
参考资料:http://developer.51cto.com/art/201108/281135.htm
http://www.cnblogs.com/ly4cn/archive/2006/08/04/467550.html
http://www.cnblogs.com/whiteyun/archive/2009/08/10/1542913.html
http://blog.csdn.net/jphaoren/article/details/5807578