• lua学习笔记


          公司有个项目涉及到网络通信,用到了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

           

  • 相关阅读:
    Bioinfomatics dataset
    在Vue中使用sass和less,并解决报错问题(this.getOptions is not a function)
    axios获取文件流并下载文件
    原码,反码,补码总结
    leetcode_sql
    Mysql中Limit用法三个简单事例
    idea新建maven项目没有target文件夹
    重启mysql
    Windows下载安装netcat(nc)命令
    启动hive
  • 原文地址:https://www.cnblogs.com/chenxl/p/4127268.html
Copyright © 2020-2023  润新知